一、block 修饰词需要使用 copy 把保存在栈中的 blcok 拷贝到堆中,因为如果是保存在栈中的block,他会随着函数调用结束被销毁。从而导致我们在执行一个包含block的函数之后,就无法再访问这个block。因为(函数结束,函数栈就销毁了,存在函数里面的block也就没有了),我们再使用block时,就会产生空指针异常。如果是堆中的block,也就是copy修饰的block。他的生命 周期就是随着对象的销毁而结束的。只要对象不销毁,我们就可以调用的到在堆中的block。
二、在声明block属性时需要确认在调用block时另一个线程有没有可能去修改block,如果确定不会有这种情况发生的话,那么block属性声明可以用nonatomic。如果不肯定的话,那么首先需要声明block属性为atomic,但是有了atomic来保证基本的原子性还是没有达到线程安全的,接着在调用时需要把block先赋值给本地变量,以防止block突然改变。
三、如果在 block 中使用外部变量需要使用__block
关键字,提到__block
就要明白在 block 的使用中__block
与__weak
的区别。
1.__block
不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak
只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block
对象可以在block中被重新赋值,__weak
不可以。
4.__block
对象在ARC下可能会导致循环引用,非ARC下会避免循环引用,__weak
只在ARC下使用,可以避免循环引用。
PS:__unsafe_unretained
修饰符可以被视为iOS SDK 4.3以前版本的__weak
的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。
网友评论