Objective-C / Blocks - Isn't this a retain cyc

2019-06-12 10:11发布

@interface ClassA : NSObject

@property (strong, nonatomic) dispatch_queue_t dispatchQ;
@property (strong, nonatomic) NSString *string;

@end

@implementation ClassA

- (id)init
{
    self = [super init];
    if (self) {
        _dispatchQ = dispatch_queue_create("com.classa.q", NULL);
    }

    return self;
}

- (void)longRunningTaskWithCompletion:(void(^)(void))completion
{
    dispatch_async(self.dispatchQ, ^{

        for (int i = 0; i < 10000; i++) {
            NSLog(@"%i", i);
        }

        dispatch_sync(dispatch_get_main_queue(), ^{
            self.string = @"Class A Rocks!";

            if(completion) {
                completion();
            }
        });
    });
}

@end

I'm thinking this code creates a retain cycle because the block in -longRunningTaskWithCompletion: captures self (to set the string property) in a block and adds the block to the dispatch queue property.

2条回答
戒情不戒烟
2楼-- · 2019-06-12 10:31

There is a retain cycle, but it's temporary. The retain cycle looks like this:

  • self retains dispatchQ
  • dispatchQ retains the block
  • the block retains self

When the block returns, dispatchQ releases it. At that point, the retain cycle is broken. The block is deallocated and releases self.

查看更多
放我归山
3楼-- · 2019-06-12 10:33

This is not a retain cycle. To have a retain cycle, self would need to retain the block while the block retains self. In the posted code, self does not retain the block. Therefore there is no retain cycle.

查看更多
登录 后发表回答