2016-07-28 19 views
1

我总是在GCD的块中使用__weakself的引用。大家都推荐这个。我知道在GCD中强烈提及self(测试)不能产生保留周期。 Apple建议使用自我引用__weak引用,然后使用_week引用_week引用来保证self在执行该块时不会是niliOS - GCD对自己的弱和强参照

我有以下的代码:

- (IBAction)startGCD:(id)sender { 

    GCDVC* __weak weakSelf = self; 

    [self.activityIndicator startAnimating]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1 

     // VC2* __strong strongSelf = weakSelf; 

     [weakSelf.proArray addObject:@"2"]; 

     [NSThread sleepForTimeInterval:10]; 

     NSLog(@"%@",weakSelf.proArray); 

     dispatch_async(dispatch_get_main_queue(), ^{ // 2 
      [weakSelf.activityIndicator stopAnimating]; 
     }); 
    }); 

} 

试验1 我按下按钮和指示器在打转。在GCD完成和GCDViewController被释放之前,我按下后退按钮。

测试2 然后,我取消了对自我的强烈提及,并执行相同的过程。在块完成工作之前,GCDViewController不会被释放。但随后发布。

测试3 现在,如果我直接引用自(不__weak__strong)我有测试2

所以,如果我想,以确保自身不会是零的具体行为当该块被执行时,使用__strong参考__weakself的引用是什么意思?我在这里想念什么?是否会改变Test 2 & 3的结果?

+0

在块内部创建一个强引用,以防止块在运行时自我释放的任何情况。 – dan

+0

是的,我知道。但是__strong和自己直接打电话给自己的区别是什么?如果我直接打电话给自己,我会像__strong一样增加留数。并且输出在两种情况下都是相同的 – BlackM

+0

如果您直接在块中引用self,那么只要block在周围,就可以防止自我被释放。在块外部创建弱自我,然后其内部强壮的自我允许自我被解除分配,而块在其周围并且仅在块正在运行时阻止它。 – dan

回答

5

当我在 GCD的块中时,我总是使用__weak引用自我。大家都推荐这个。

不,我不知道任何人推荐。在有保留周期的情况下,弱引用是合理的。但是,一个块是否应该捕获弱或强引用任何对象(包括一个self点)取决于问题的代码的特定内存管理的设计和

我知道强引用自(测试)在GCD中不能产生 保留周期。

在全局或主队列上传递一个块到dispatch_async永远不会产生保留周期。

现在,如果我直接引用自(不__weak或__strong)我有 确切的行为与测试2.

也许你没有看到在这种情况下任何区别。但他们总体上有不同的行为。基本上,你的问题是捕获对self指向的对象的强或弱引用的块之间有什么区别。

不同之处在于,如果当前对象(由self指向的对象)已被每个其他持有该对象的对象释放,除了潜在的块以外,并且该块之后会异步执行。

  • 如果块捕获到对当前对象的强引用,那么该引用将在整个时间内保持对象存活。所以对象仍然活着,我们可以使用它并向它发送消息等。
  • 如果块捕获到当前对象的弱引用,那么当前对象已被释放,当最后一次强引用它时被释放。所以这个块的弱引用在这个时候是nil,并且该块不会对它做任何事情(它要么检查strongSelf,要么在它看到它是nil时返回,要么将它发送到strongSelf这是它不做任何事)。

所以在一种情况下,东西就完成了,在另一种情况下,什么都不做。

如果您的案例中的当前对象是某个UI元素,如视图或视图控制器,那么只要它位于视图层次结构中,它将被视图层次结构中的事物保留,因此您需要从这个视图/视图控制器中退出,以便在没有其他任何内容强烈引用它的情况下。

就你而言,你在块内所做的全部工作是[weakSelf.activityIndicator stopAnimating];,即对用户界面的更改。这个命令是否运行并不重要,因为请记住,包含该命令的视图已经停止显示。没有人能看到这个活动指标。那么,如果你停下来,它有什么不同?但这是特定于这种情况。一般情况下,你可以想象块内部的命令改变了一些全局状态,或者通过网络发送了一些东西,如果你做或不做,它们之间有很大的区别。