在ARC中保留计数

时间:2014-02-25 08:19:16

标签: ios automatic-ref-counting retaincount

我正在我的项目中使用外部库,该库正在ARC环境中构建。根据库,仅当retain count = 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;
   }  
}

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

3 个答案:

答案 0 :(得分:0)

在ARC中,您必须将对象设置为nil才能维护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
}

答案 1 :(得分:0)

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

更新:
通过遵循您的代码,我看到以下内容:
在此代码中,您正在创建BroadCastClient的实例并将其添加到NSDictionnarystream),但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];
}

现在这里是disconnect stream字典(我不知道这个对象是什么,因为在你的代码中我没有看到任何创建或添加它)对象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

答案 2 :(得分:0)

看起来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];
}