系统block的 self 是否需要弱引用?

在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,代码如下:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__weak __typeof__(self) weakSelf = self;
dispatch_async(queue, ^{
   __typeof__(self) strongSelf = weakSelf;
  [strongSelf assitFunc1];
});

问题一: 系统block为何 self 不用弱引用 如下:

[UIView animateWithDuration:duration  animations:^{ 
  [self.superview layoutIfNeeded]; 
}];

 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
 self.someProperty = xyz; 
 }];

[[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification" 
                      object:nil 
                       queue:[NSOperationQueue mainQueue]
                       usingBlock:^(NSNotification * notification) {
                                          self.someProperty = xyz; 
}];

这些系统的 block 不会造成循环引用的原因是,这是个类方法,block 不被 self 持有 ,而是其他负责的对象持有,同时不产生循环引用,block 持有了 self, block 运行结束会被释放,同时释放掉对 self 的持有, 所以不存在self 和 block 的循环引用问题,不需要weak 弱引用

问题二:什么时候在 block 里面可以用 self,不需要使用 weak self

之所以需要弱引用本身,是因为怕对象之间产生循环引用,引起程序崩溃,内存泄漏!
所谓“引用循环”是指双向的强引用,所以那些“单向的强引用”(block 强引用 self )没有问题

问题三:为什么 block 里面还需要写一个 strong self,如果不写会怎么样?

在 block 中先写一个 strong self,其实是为了避免在 block 的执行过程中,突然出现 self 被释放的尴尬情况,那么多半情况下会 Crash.

总结:

1.block 不形成循环引用,并且想让block代码什么情况下都执行:两种方式:A全部使用self就行;B外面定义weak,block里面用strong,也行,多此一举。

2.block 不形成循环引用,并且想让block代码在当前VC释放的情况下不执行:两种方式:A外面定义weak,里面使用weak,然后注意nil可能会crash的地方(加判断);B外面定义weak,block里面使用strong(或者直接使用self),自己加if判断,否是在当前页面,不在当前页面不执行。

3.block 循环引用,想让block代码无论如何都执行:必用weak。block里面用strong。

4.block 循环引用,想让block代码在当前VC释放的情况下不执行:两种方式:A必用weak,block里面用strong,则自己加if判断不在当前页面就不执行;B,block里面使用weak,注意nil可能导致crash的地方。

重点注意:弄清楚block到底被谁持有,例如UIView的animateWithDuration方法,大部分时候写的dispatch,传参等,都没有成环,是不用定义weak和strong的。

你可能感兴趣的:(系统block的 self 是否需要弱引用?)