我有一个关于 iOS block 中对 self 的强引用和弱引用的问题。我知道在 block 内引用 self 的正确方法是在 block 外创建一个弱引用,然后在 block 内创建一个对该弱引用的强引用,如下所示:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
typeof(self) strongSelf = weakSelf;
NSLog(@"%@", strongSelf.someProperty);
});
但是,如果您有嵌套 block 会发生什么?一套引用文献就够了吗?或者您是否需要为每个 block 设置一个新集?例如,下列哪项是正确的?
这个:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
typeof(self) strongSelf = weakSelf;
NSLog(@"%@", strongSelf.someProperty);
dispatch_async(dispatch_get_main_queue(), ^ {
strongSelf.view.frame = CGRectZero;
});
});
或者这个:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
typeof(self) strongSelf = weakSelf;
NSLog(@"%@", strongSelf.someProperty);
__weak typeof(strongSelf) weakSelf1 = strongSelf;
dispatch_async(dispatch_get_main_queue(), ^ {
typeof(strongSelf) strongSelf1 = weakSelf1;
strongSelf1.view.frame = CGRectZero;
});
});
非常感谢任何信息或解释!
最佳答案
你不需要做两组弱引用。使用 block 要避免的是保留循环——两个对象在不必要的情况下使彼此保持事件状态。
如果我有一个具有此属性的对象:
@property (strong) void(^completionBlock)(void);
我有这个方法:
- (void)doSomething
{
self.completionBlock = ^{
[self cleanUp];
};
[self doLongRunningTask];
}
当我将它存储在 completionBlock
属性中时,该 block 将保持事件状态。但由于它在 block 内引用 self
,因此该 block 将保持 self
事件直到它消失——但这不会发生,因为它们都在相互引用。
在这个方法中:
- (void)doSomething
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self cleanUp];
}];
[self doLongRunningTask];
}
您不需要对 self
进行弱引用。该 block 将保持 self
事件,因为它从内部引用 self
,但由于我们所做的只是将 block 交给 [NSOperationQueue mainQueue]
,self
并没有使 block 保持事件状态。
希望这会有所帮助。
关于iOS block 和对自身的强/弱引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19018456/