变量限定符
对变量使用以下生命周期限定符:
__strong
__weak
__unsafe_unretained
__autoreleasing
- __strong 是默认限定符。只要有一个指向对象的强指针,对象就保持“活动”状态(retain)。
- __weak 指定一个引用,该引用不保持被引用对象的活动状态(unretain)。当该对象没有被强引用时,弱引用会被重置为nil。
- __unsafe_unretained 指定一个引用,该引用不保持被引用对象的活动状态(unretain),并且在该对象没有被强引用时不重置为nil。如果它引用的对象被释放,指针就会悬空(野指针)。
- __autoreleasing 用于修饰引用传递的参数(id *),并在返回时自动释放这些参数。
__weak 和 __unsafe_unretained 的区别:
当对象没有被强引用时,__weak 弱引用会被重置为nil,__unsafe_unretained 指针悬空。因此,__weak 更安全,__unsafe_unretained 更高效(其性能提升可忽略不计)。 在确保安全的前提下,才可使用 __unsafe_unretained 。
正确地修饰变量
在对象变量声明中使用限定符时,正确的格式是:
ClassName * qualifier variableName;
其他变体在技术上是不正确的,但是编译器会“原谅”它们。
注意通过引用传递的对象
下面的代码会正常执行:
NSError *error;
BOOL OK = [myObject performOperationWithError:&error];
if (!OK) {
// Report the error.
// ...
但是,其隐式的声明是错误的:
NSError * __strong error;
方法声明通常如下:
- (BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
因此,编译器会重写代码:
NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
// Report the error.
// ...
网友评论