在ARC中进行保留计数



我在我的项目中使用了一个外部库,该库是在ARC环境中构建的。根据库,只有当保留计数为0时,套接字对象才会被解除分配。据我所知,在ARC中不可能使用保留计数,但我被迫删除套接字对象的所有引用,这在我的项目中是不可能的。如何解决此问题?代码问题的要点如下:

-(void)callConnect{
for(int i = 0; i<[userArray count];i++){
[self connect:(NSString*)[userArray objectAtIndex:i]];
}
}
-(void)connect:(NSString *)username{
RTMPCLient *socket = [[RTMPClient alloc] init];
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username];
}
-(void)disconnect{
for(int i = 0; i<[userArray count];i++){
[stream objectForKey:[NSString stringWithFormat:@"%@",[userArray objectAtIndex:i]]] = nil; //error on this line
BroadCastClient *tempStream = [stream objectForKey:[userArray objectAtIndex:i]];
tempStream = nil;
}  
}

我正在尝试使流对象为零,这会产生错误。无法将其保存为另一个变量,因为它增加了套接字对象的引用。将tempStream设置为nil不会影响创建的原始实例。我想在disconnect方法中从流中删除套接字对象的引用。我该怎么做?

ARC会将不可见的release消息放在代码中(在连接中),但array会对它们有强引用,因此它们会留在内存中。您在disconnect中所要做的就是从集合([stream removeAllObjects][userArray removeAllObjects])中删除所有对象,然后集合将释放它们

更新:
通过遵循您的代码,我看到以下内容:
在这段代码中,您正在创建BroadCastClient的实例,并将其添加到NSDictionnary(stream)中,但NSDictionary没有引用它,因此它将在方法调用后被释放

-(void)callConnect{
for(int i = 0; i<[userArray count];i++){
[self connect:(NSString*)[userArray objectAtIndex:i]];
}
}
-(void)connect:(NSString *)username{
RTMPCLient *socket = [[RTMPClient alloc] init];
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username];
}

现在这里是disconnectstream字典(我不知道这个对象是什么,因为在你的代码中我看不到任何创建或添加到它的东西)对象BroadCastClient由字典保留,所以只需从字典中删除这个对象就可以将其从内存中释放出来(假设你没有其他强引用)

-(void)disconnect{
for(int i = 0; i<[userArray count];i++){
[stream objectForKey:[NSString stringWithFormat:@"%@",[userArray objectAtIndex:i]]] = nil; //error on this line
BroadCastClient *tempStream = [stream objectForKey:[userArray objectAtIndex:i]];
tempStream = nil;
}  
}

我建议您对代码进行一些重构,但在此之前,请有一些时间阅读以下指南:https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/Articles/mmPractical.html

在ARC中,您只需将对象设置为零即可维护RC。所以你可以用下面的方法来做。

-(void)disconnect{
socket = nil;
stream = nil;
stream = nil;
}
-(void)connect:(NSString *)username{ 
if (socket != nil )
socket = nil;
RTMPCLient *socket = [[RTMPClient alloc] init];
if (stream != nil ) 
stream = nil;
BroadCastClient *stream = [[BroadCastClient alloc] initWithClient:socket];
NSMutableDictionary *stream = [NSMutableDictionary dictionaryWithObject:stream forKey:username]; // Make it using alloc...then you must use nil only
}

看起来streamNSMutableDictionary *类型的实例变量。因此,如果你想删除stream字典中的引用,你可以这样做:

- (void)disconnect {
for (int i = 0; i<[userArray count]; i++) {
[stream removeObjectForKey:[userArray objectAtIndex:i]];
}  
}
// Alternative version using Fast Enumeration:
- (void)disconnect {
for (id key in userArray) {
[stream removeObjectForKey:key];
}
}

但是,如果您只想从stream中删除所有引用,只需执行:

- (void)disconnect {
[stream removeAllObjects];
}

最新更新