Search code examples
cocoa-touchcocoaasihttprequestautomatic-ref-countingretain

Fix warning "Capturing [an object] strongly in this block is likely to lead to a retain cycle" in ARC-enabled code


In ARC enabled code, how to fix a warning about a potential retain cycle, when using a block-based API?

The warning:
Capturing 'request' strongly in this block is likely to lead to a retain cycle

produced by this snippet of code:

ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...

[request setCompletionBlock:^{
    NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.rawResponseData error:nil];
    // ...
    }];

Warning is linked to the use of the object request inside the block.


Solution

  • Replying to myself:

    My understanding of the documentation says that using keyword block and setting the variable to nil after using it inside the block should be ok, but it still shows the warning.

    __block ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...
    
    [request setCompletionBlock:^{
        NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.responseData error:nil];
        request = nil;
    // ....
    
        }];
    

    Update: got it to work with the keyword '_weak' instead of '_block', and using a temporary variable:

    ASIHTTPRequest *_request = [[ASIHTTPRequest alloc] initWithURL:...
    __weak ASIHTTPRequest *request = _request;
    
    [request setCompletionBlock:^{
        NSDictionary *jsonDictionary = [[CJSONDeserializer deserializer] deserialize:request.responseData error:nil];
        // ...
        }];
    

    If you want to also target iOS 4, use __unsafe_unretained instead of __weak. Same behavior, but the pointer stays dangling instead of being automatically set to nil when the object is destroyed.