objc中的修饰符

__strong 修饰符

__strong修饰符是id类型和对象类型默认的所有权修饰符。id和对象类型在没有明确指定所有权修饰符时,默认为__strong修饰符。以下两行代码相同:

1
2
id obj = [[NSObject alloc] init];
id __strong obj = [[NSObject alloc] init];

__strong修饰符能对对象持有强引用,保证对象在声明周期结束前都不会被释放。而在变量超出其作用域时,强引用失效,因此自动释放对象。这样能够使ARC简单而有效。

__weak 修饰符

可是,光有__strong修饰符会导致“循环引用”的问题,因此引发内存泄漏。__weak修饰符能够避免这样的问题。

弱引用不能持有对象实例,如果编译以下代码,编译器会发出警告:

1
id __weak obj = [[NSObject alloc] init];

__weak修饰符有一个优点。在持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效且处于nib被赋值的状态。

__weak修饰符只能用于iOS5以上及OS X Lion以上版本的应用程序。在低版本的程序中可使用__unsafe_unretained修饰符来代替。

__unsafe_unretained 修饰符

尽管ARC式的内存管理是编译器的工作,但附有__unsafe_unretained修饰符的变量不属于编译器的内存管理对象。

同__weak修饰符一样,用__unsafe_unretained修饰的变量也不能持有对象。

之所以叫做”unsafe”,是因为附有__unsafe_unretained修饰符的变量所指向的对象如果已经被废弃,这个变量并不会置nil,而变成了一个悬垂指针,如果访问它,程序就会崩溃。

__autoreleasing 修饰符

在ARC有效时,将不能使用autorelease方法和NSAutoreleasePool类。但是,autorelease功能还是起作用的。

ARC有效时,autorelease功能可以这样写:

1
2
3
@autoreleasepool {
id __autorelease obj = [[NSObject alloc] init];
}

可以理解为,在ARC有效时,用@autoreleasepool块替代NSAutoreleasePool类,用附有__autorelease修饰符的变量替代autorelease方法。

__block 修饰符

在使用Block时,自动变量值截取只能保存执行Block语法瞬间的值。保存后就不能改写该值。若想在Block语法的表达式中将值赋给在Block语法外声明的自动变量,需要在该自动变量上附件__block修饰符。

1
2
3
4
__block int val = 0;
void (^blk)(void) = ^{val = 1;}
blk();
printf("val = %d\n", val);

该源代码的执行结果为:

1
val = 1