强化和弱化导致问题

时间:2015-08-11 03:34:49

标签: ios objective-c

我有一个代码可以做这样的事情:

@weakify(self);
dispatch_group_notify(myGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    @strongify(self);
    [self doSomething];
});

然而,"自我"似乎实际上在这个区块内是零。我甚至不知道这是可能的。我认为@weakify虚拟地创建了对self的弱引用,让我们称之为__weakSelf。然后,当我使用@strongify时,它会将一个局部变量分配给__weakSelf

为什么self nil在[self doSomething]行?这是否意味着self已经被释放,因为dispatch_group_notify还没有被self或某些东西抓住?因此self随时可以获得dealloc? (例如当我的块实际运行时)?

1 个答案:

答案 0 :(得分:3)

你问:

  

为什么self nil位于[self doSomething]行?

因为它在到达nil行之前是@strongify(self)。即它在通知块开始之前被解除分配。

  

这是否意味着self已经被释放,因为dispatch_group_notify没有保留self或什么?

是的。或者,更准确地说,selfdispatch_group_notify指定的块被调用时已经被释放。

这就是weakify的全部目的:确保self块中dispatch_group_notify的出现不会导致self被保留。块中strongify的目的是,如果self尚未发布,请确保在块运行时不释放它,但如果它在 {{之后> 1}},但之前到达weakify行,然后继续让它取消分配,让strongify成为self

-

典型的用例是当一个人发起一堆异步请求并且有一个通知块在下载完成时更新UI。您可以使用nil来引用视图控制器,因此如果在下载完成之前关闭视图控制器,则通知块将不会挂起(如果用户解除视图,这是有意义的)控制器,没有必要挂在视图控制器引用上来更新不再存在的视图。但是你可以在该块中使用weakify,这样如果在通知块启动之前视图控制器没有被解除,请确保在通知块运行时未释放通常是一个不太重要的问题,但有时很重要。)