capturing self strongly in this block is likely to lead to a retain cycle capturing self strongly in this block is likely to lead to a retain cycle objective-c objective-c

capturing self strongly in this block is likely to lead to a retain cycle


The capture of self here is coming in with your implicit property access of self.timerDisp - you can't refer to self or properties on self from within a block that will be strongly retained by self.

You can get around this by creating a weak reference to self before accessing timerDisp inside your block:

__weak typeof(self) weakSelf = self;[player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)                                     queue:nil                                usingBlock:^(CMTime time) {                                                current+=1;                                                if(current==60)                                                {                                                    min+=(current/60);                                                    current = 0;                                                }                                                 [weakSelf.timerDisp setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];                                            }];


__weak MyClass *self_ = self; // that's enoughself.loadingDidFinishHandler = ^(NSArray *receivedItems, NSError *error){    if (!error) {       [self_ showAlertWithError:error];    } else {       self_.items = [NSArray arrayWithArray:receivedItems];       [self_.tableView reloadData];    }};

And one very important thing to remember:do not use instance variables directly in block, use it as a properties of weak object, sample:

self.loadingDidFinishHandler = ^(NSArray *receivedItems, NSError *error){        if (!error) {           [self_ showAlertWithError:error];        } else {           self_.items = [NSArray arrayWithArray:receivedItems];           [_tableView reloadData]; // BAD! IT ALSO WILL BRING YOU TO RETAIN LOOP        } };

and don't forget to do:

- (void)dealloc {    self.loadingCompletionHandler = NULL;}

another issue can appear if you will pass weak copy of not retained by anybody object:

MyViewController *vcToGo = [[MyViewCOntroller alloc] init];__weak MyViewController *vcToGo_ = vcToGo;self.loadingCompletion = ^{    [vcToGo_ doSomePrecessing];};

if vcToGo will be deallocated and then this block fired I believe you will get crash with unrecognized selector to a trash which is contains vcToGo_ variable now. Try to control it.


Better version

__strong typeof(self) strongSelf = weakSelf;

Create a strong reference to that weak version as the first line in your block. If self still exists when the block starts to execute and hasn’t fallen back to nil, this line ensures it persists throughout the block’s execution lifetime.

So the whole thing would be like this:

// Establish the weak self reference__weak typeof(self) weakSelf = self;[player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)                                 queue:nil                            usingBlock:^(CMTime time) {    // Establish the strong self reference    __strong typeof(self) strongSelf = weakSelf;    if (strongSelf) {        [strongSelf.timerDisp setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];    } else {        // self doesn't exist    }}];

I have read this article many times. This is an excellent article by Erica Sadun on How To Avoid Issues When Using Blocks And NSNotificationCenter


Swift update:

For example, in swift a simple method with success block would be:

func doSomeThingWithSuccessBlock(success: () -> ()) {    success()}

When we call this method and need to use self in the success block. We'll be using the [weak self] and guard let features.

    doSomeThingWithSuccessBlock { [weak self] () -> () in        guard let strongSelf = self else { return }        strongSelf.gridCollectionView.reloadData()    }

This so-called strong-weak dance is used by popular open source project Alamofire.

For more info check out swift-style-guide