__strong
强引用所有权修饰符,会增加对象的引用计数,即变量会持有改对象。在变量超出作用域时,对象会被自动释放、废弃并赋值nil。
id __strong obj1 = [NSObject new];
// 等效于
id obj1 = [NSObject new];
__weak
弱引用所有权修饰符,不会增加对象的引用计数。在可能导致对象间循环引用的问题上,应使用此修饰符。在变量超出作用域时,由于未持有对象,因此会被直接废弃并赋值nil。
id obj1 = [Test new];
id obj2 = [Test new];
[obj1 setObj:obj2];
[obj2 setObj:obj1];
// 上述情况如果Obj是strong类型就会使得obj1、obj2相互持有对方,导致内存泄露。
// 因此在Test类中,应把Obj对象声明为weak。
__unsafe_unretained
与__weak修饰符类似,在iOS4中用来代替__weak修饰符。但用此修饰符修饰的变量,在超出作用域被废弃后,并不会被赋值nil。此时再次访问改变量,由于该变量成为了野指针(指向不存在的地址),可能会导致程序崩溃。
__autoreleasing
autorelease修饰符修饰的对象会被自动注册到NSAutoreleasingPool(自释放池)中,在自释放池对象释放时,会一起释放。由于主线程的runloop会对自释放池进行管理,所以并不需要显示的使用自释放池,但对于一些消耗内存的操作,比如图片读取,显式的使用自释放池会加快内存的释放。
// 模式一
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// 一些修饰为autorelease的对象
[pool drain];
// 模式二
@autorelease{
id __autorelease obj = [[Test alloc] init];
}
在访问__weak修饰的对象时,为了避免对象被突然释放,因此需要将其注册到autoreleasepool中,这样在@autoreleae{}快结束之前,该对象能够一直存在。
id __weak obj1 = obj0;
id __autorelease obj2 = obj1;
[obj2 method];
id * 类型默认为 id __autoreleasing *
retain
使用retain修饰的变量将增加对象的引用计数,从而持有对象。在ARC模式下已废弃。
assign
使用assing修饰的变量不会增加对象的引用计数,与weak类似。确切的说是与__unsafe_unretained类似,在对象被释放时,变量不会自动赋值nil,因此会变成野指针(指向一个不存在的地址),再次访问该变量可能会导致程序崩溃。
__bridge
类型转换修饰符。如果需要把对象类型变量复制给void* 或者逆向赋值时需要使用__bridge转换
id obj = [Test new];
void * p = (__bridge void *)obj; // p 不会持有obj
void * p = (__bridge_retained void *)obj; // p 会持有obj
id obj2 = (__bridge_transfer id)p;
__block
详见iOS-Block。
网友评论