Search code examples
restkitobjective-c-blocks

When using @weakify, @strongify, do I have to use __block?


Let's say my class have a instance variable called hotspotsOperation (I'm using RestKit) and is used inside a block (a NSOperation by RestKit). I do this because I want to be able to cancel the ongoing request. However I have a question about retain cycles, __block. Basically, do I have to use __weak when using weakify/strongify? And another question, if I don't use weakify/strongify but change hotspotsOperation from strong to weak, the analyzer says there is no retain cycle, is that right? Is better to use weak rather than weakify/strongify? What happens with self in this case, is retained? Thanks a lot for any suggestion.

#import "HotspotsService.h"
#import "Constants.h"
#import "Restkit.h"
#import "Hotspot.h"
#import <EXTScope.h>

@interface HotspotsService()
@property (nonatomic,strong) RKObjectManager *objectManager;
@property (nonatomic,strong) RKObjectRequestOperation *hotspotsOperation;
@end

@implementation HotspotsService

-(id) init {
    self=[super init];
    if (self) {
        // restkit
        // mapping
        // response
    }
    return self;
}

-(void) hotspotsWithRadius:(NSUInteger)rad center:(CLLocationCoordinate2D)coordinate onSuccess:(void(^)(NSArray *hotspots))success onFailure:(void(^)(NSError *error))fail {
    [self cancelHotspotsRequest];
    NSDictionary *params = // params
    self.hotspotsOperation = [self.objectManager appropriateObjectRequestOperationWithObject:nil method:RKRequestMethodGET path:kSolrPath parameters:params];
    @weakify(self);
    [self.hotspotsOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        @strongify(self);
        self.hotspotsOperation=nil;
        success(mappingResult.array);
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        @strongify(self);
        self.hotspotsOperation=nil;
        fail(error);
    }];
    [self.objectManager enqueueObjectRequestOperation:self.hotspotsOperation];
}

-(void) cancelHotspotsRequest {
    [self.hotspotsOperation cancel];
    self.hotspotsOperation=nil;
}

@end

Solution

  • I would make hotspotsOperation property weak, because you are passing the operation off to RestKit to manage and you only care about it for that lifetime - you have no interest in owning it past this lifetime. That also means you don't need to capture self in the block.

    If you're capturing self in a block that is retained by an object owned by self then you should use a weak reference. How you do that is up to you, but @weakify seems pretty convenient and simple.