关于 OC 中的 @weakify

关于 @weakify@strongify 的一些小知识。

1
2
3
4
@weakify(self);
block = ^() {
@strongify(self);
}

相当于如下代码:

1
2
3
4
__weak typeof(self) weakSelf = self;
block = ^(){
__strong typeof(weakSelf) self = weakSelf;
};

https://halfrost.com/ios_block_retain_circle/#toc-12

https://www.jianshu.com/p/bc794fa07167

https://stackoverflow.com/questions/28305356/ios-proper-use-of-weakifyself-and-strongifyself

How @strongify works
After @strongify is called, self will have a different pointer address inside the block than it will outside the block. That’s because @strongify declares a new local variable called self each time. (This is why it suppresses the -Wshadow warning, which will “warn whenever a local variable shadows another local variable.”) It’s worth reading and understanding the implementation of these functions. So even though the names are the same, treat them as separate strong references.

Using @strongify in your code

  • (void)someMethod {
    if (self.someBOOL) {
    @weakify(self);
    _someObjectInstanceVar = [Object objectWithCompletionHandler:^{
    @strongify(self);
    // self reference #1
    if (self.someProperty) {
    @weakify(self);
    // self reference #2
    [[Async HTTPRequest] sendAWithID:self.property.id completionHandler:^(void (^)(NewObject *newObject) {
    @strongify(self);
    // self reference #3
    @weakify(self);
    [self showViewWithObject:newObject handler:^{
    // self reference #4
    @strongify(self);
    [self reloadData];
    }];
    }];
    }
    }];
    // etc…
    }

However, remember that after your first use of @strongify, self will refer to local, stack variables. These will typically get destroyed when the scope in which they’re defined ends (as long as you aren’t storing them to properties or using them in a nested block). So based on the code you showed, you only need it after // self reference #1.