弱自我使用,阻止内存管理

时间:2014-07-17 13:59:22

标签: ios objective-c memory-management objective-c-blocks

关于所有这些弱势和强烈的自我有很多问题,但我希望你们看看我的特定例子:

- (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);
             });
         }]; 
     });
 }];
}

这里的一切都是正确的吗?也欢迎您建议重构

2 个答案:

答案 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(寻找“你应该正确装饰变量。”)