简体   繁体   中英

Strong reference to a weak references inside blocks

Why is it necessary to have a strong reference to a weak reference inside a block?

I understand that having a weak reference inside the block will avoid retain cycles. But why must there be a strong reference to the weak one again?

Background:
As described by Mason this is best practice.

I know the proper way to refer to self inside a block is to create a weak reference outside the block, and then a strong reference to that weak reference inside the block[...]

Example:

__weak typeof(self) weakSelf = self;
void (^someBlock)(id) = ^(id data){
    typeof(self) strongSelf = weakSelf;
    // code using strongSelf
});

Imagine that the last remaining strong reference to self is held on a different thread to the one that your block runs on.

Now this happens:

__weak typeof(self) weakSelf = self;
void (^someBlock)(id) = ^(id data){
    if (weakSelf != nil) {
       // last remaining strong reference released by another thread. 
       // weakSelf is now set to nil.
       [myArray addObject:weakSelf];
    }
});

This will crash with an NSInvalidArgument exception for adding nil to an array.

Making the reference strong before use removes the potential race condition and ensures that the pointer will always point to the same object.

If you are 100% certain that an object will only ever be referenced by one thread, it isn't strictly necessary to do this. But it's bad practice to make that assumption.

It's not inherently necessary, but the general idea is to make sure that the object pointed to by weakSelf is not dealloc'ed while the block is executing. Creating the strong reference has the side effect of retaining the object. That retain will be released by ARC when the strong reference goes out of scope. It's largely defensive. Generally speaking, you should aim to provide other (better) guarantees that your system remains stable during block execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM