__weak 修饰符
-
id obj0 = [[NSObject alloc] init];
id
和对象类型在没有明确指定所有权修饰符时,默认为__strong
修饰符。上句等同于id __strong obj0 = [[NSObject alloc] init];
-
__weak
修饰符还有一个优点,在持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效且处于nil被赋值的状态(空弱引用):
id __weak obj1;
- (void)knowARC{
id obj0 = [[NSObject alloc] init];
obj1 = obj0;
NSLog(@"A: %@",obj1);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self knowARC];
NSLog(@"B: %@",obj1);
}
//输出结果
2017-09-26 14:12:26.437282+0800 WCCTestProj[1611:82405] A: <NSObject: 0x600000017df0>
2017-09-26 14:12:26.437464+0800 WCCTestProj[1611:82405] B: (null)
代码执行情况如下:
像这样,可以使用__weak
修饰符可避免循环引用,通过检查附有__weak
修饰符的变量是否为nil,可以判断被赋值的对象是否已经废弃。
__unsafe_unretained修饰符
__unsafe_unretained
是不安全的所有权修饰符,尽管ARC式的内存管理是编译器的工作。但附有__unsafe_unretained
修饰符的变量不属于编译器的内存管理对象,这一点在使用时要注意。
id __unsafe_unretained obj1;
- (void)knowARC{
id obj0 = [[NSObject alloc] init];
obj1 = obj0;
NSLog(@"A: %@",obj1);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self knowARC];
NSLog(@"B: %@",obj1);//此行崩溃,如果是__weak修饰的变量此时可以输出null
//如果运行正常知识碰巧而已
}
//输出结果
2017-09-26 14:30:07.691681+0800 WCCTestProj[1714:89691] A: <NSObject: 0x600000012490>
2017-09-26 14:30:07.691884+0800 WCCTestProj[1714:89691] *** -[NSObject isProxy]: message sent to deallocated instance 0x600000012490
代码执行情况如下:
在使用
__unsafe_unretained
修饰符时,赋值给附有__strong
修饰符的变量时有必要确保被赋值的对象确实存在。
__autoreleasing修饰符
自己测试的结果:
NSString *str = @"abc";
str = @"ddd";
NSLog(@"%@",str);
//输出结果如下
(lldb) p str
(__NSCFConstantString *) $0 = 0x000000010ea66280 @"abc" //此处输出的是str地址指向的值
(lldb) p *str
(NSString) $1 = {
NSObject = {
isa = __NSCFConstantString
}
}
(lldb) p &str
(NSString **) $2 = 0x00007fff5119bc08 //这里(NSString **)与&str 是一样的,等价的,都是表示str地址
(lldb) p str
(__NSCFConstantString *) $3 = 0x000000010ea662a0 @"ddd"
(lldb) p *str
(NSString) $4 = {
NSObject = {
isa = __NSCFConstantString
}
}
(lldb) p &str
(NSString **) $5 = 0x00007fff5119bc08 //此处是str变量的地址,而不是str的值
(lldb) p **str
error: indirection requires pointer operand ('NSString' invalid)
(lldb) p *&str
(__NSCFConstantString *) $6 = 0x000000010ea662a0 @"ddd" //此处是取str地址的值
(lldb)