ARC下的Block简述
一、Block的机制
理解block的核心就在于:
当block只使用变量的值时,那么只需要将变量的值作为实参传给block中的形参。
如果这个变量是一个指向某个对象的指针,那么block是strong持有这个对象的。NSArray *array = @[10]; void (^block)() = ^ { NSLog(@"array = %@", array); };
当block中会改变变量的值时,那么需要将变量的地址(即指向变量的指针)作为实参传给block中的形参。此时这个变量需要用__block修饰。
__block NSArray *array = @[10]; void (^block)() = ^ { array = nil; };
二、栈上和堆上
另外,要了解的就是
如果block是在栈上创建的,那么当出了作用域之后block就会被销毁,其自然也就不会再strong持有对象了。
但是如果将block copy到了堆上,那么就有问题了。
如果一个对象有一个block成员变量,而这个block中又使用到了self,那么这两个对象互相引用,便会产生内存泄露。typedef void(^Block)(); @property (nonatomic, copy, readwrite) Block block; self.block = ^{ NSLog(@"self.name = %@", self.name); };
处理这个问题的方法就是:
__weak __typeof(self) *weakSelf = self; self.block = ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; NSLog(@"self.name = %@", weakThis.name); };
为什么这样处理就没有问题了呢?
因为block中使用到的是一个weak弱引用对象的指针,这样block就也不会去strong持有这个对象,自然就没有内存泄露的问题了。
可是,strongSelf又是做什么的呢?strongSelf是保证一旦进入block之后,self就不能再被释放直到block块结束。
另外,要说明的一点是,不仅要考虑互相引用,也要考虑循环引用。