关于所有这些弱势和强烈的自我有很多问题,但我希望你们看看我的特定例子:
- (void)getItemsWithCompletionHandler:(void (^)(NSArray*items))completionHandler {
__weak __typeof__(self) weakSelf = self;
[self doWorkWithCompletionHandler:^(Response *response) {
// this completion is not on main thread
dispatch_async(dispatch_get_main_queue(), ^{
...
[weakSelf doAnotherWorkWithCompletionHandler:^(Response *response) {
// this completions is not on main thread either
dispatch_async(dispatch_get_main_queue(), ^{
__typeof__(self) strongSelf = weakSelf;
NSArray *itemsIds = [strongSelf doWorkOnMainThread1];
NSArray *items = [strongSelf doWorkOnMainThread2];
completionHandler(items);
});
}];
});
}];
}
这里的一切都是正确的吗?也欢迎您建议重构
答案 0 :(得分:1)
如果您打开所有警告,则会收到
的警告[weakSelf doAnotherWorkWithCompletionHandler... ];
您不应该向弱对象发送消息。当被调用的方法正在运行时,弱对象可能会消失。将弱对象存储为强对象,结果为零或无。如果你再打电话
[strongSelf doAnotherWorkWithCompletionHandler... ];
你知道strongSelf == nil并且没有任何反应,或者strongSelf在方法执行时保持不为零。
答案 1 :(得分:0)
您应该检查completionHandler是否为NULL,然后调用它。
if (completionHandler) {
completionHandler(items);
}
否则,如果completionHandler为NULL,则会崩溃
如果您想在completionHandler(items)
处随时致电self == nil
,您也可以重新考虑。我这样说,因为存在轻微的不一致
在行
[weakSelf doAnotherWorkWithCompletionHandler:^(Response *response) {
如果weakSelf已经为nil,那么completionHandler
将不会被调用,结果completionHandler(items)
也不会被调用。
但是在这里:
__typeof__(self) strongSelf = weakSelf;
NSArray *itemsIds = [strongSelf doWorkOnMainThread1];
NSArray *items = [strongSelf doWorkOnMainThread2];
completionHandler(items);
如果self == nil
,则completionHandler
实际上会被调用。
当然,我看不到全貌,也许这完全无关紧要,但你可能想要考虑的事情。
更进一步,我认为你宁愿在每个场景中调用 completionHandler
,即使self == nil
在任何时候也是如此。或者在出现任何问题时为其添加错误参数。
如果你想变得超级迂腐,你可能想把__weak放在类型之后,如下:
__typeof__(self) __weak weakSelf = self;
这是首选方式:https://developer.apple.com/library/ios/releasenotes/objectivec/rn-transitioningtoarc/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4(寻找“你应该正确装饰变量。”)