Search code examples
iosautomatic-ref-countingretaincount

make retain count in ARC


I am using an external library in my project which is being build in an ARC environment. As per the library the socket object gets deallocated only when the retain count=0. As far as I know its not liable to use retain count in ARC but I am forced to remove all the reference of the socket object which is not possible in my project. How can I resolve this issue? A gist of code issue is below:

-(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;
   }  
}

I am trying to make the stream object nil which gives an error. Cannot save it another variable as it increases the references of socket object.By making the tempStream nil doesn't affect the original instance created. I want to remove the reference of socket object from stream in the disconnect method. How can I do so?


Solution

  • ARC will put the invisible release message in your code (in connect), but the array will have strong reference on them, so they will stay in memory. All you have to do in disconnect remove all the objects from your collection ([stream removeAllObjects] and [userArray removeAllObjects]) and the collection will release them.

    UPDATE:
    By following your code I see the following:
    In this code you are creating an instance of BroadCastClient and adding it to NSDictionnary (stream), but NSDictionary has no reference to it, so it will be deallocated after the method call

    -(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];
    }
    

    Now here the disconnect stream dictionary (I don't know what is this object, because in your code I don't see any creating or adding to it) the object BroadCastClient is retained by the dictionary, so just removing this object from the dictionary will free it from memory (assuming you have no other strong reference to it)

    -(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;
       }  
    }
    

    I would recommend some refactoring for your code, but before that please have some time to read this guid: https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/Articles/mmPractical.html