1.3.3 所有权修饰符

__weak 修饰符

  1. id obj0 = [[NSObject alloc] init]; id和对象类型在没有明确指定所有权修饰符时,默认为__strong修饰符。上句等同于id __strong obj0 = [[NSObject alloc] init];
  2. __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: 
2017-09-26 14:12:26.437464+0800 WCCTestProj[1611:82405] B: (null)

代码执行情况如下:


1.3.3 所有权修饰符_第1张图片

1.3.3 所有权修饰符_第2张图片

像这样,可以使用__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: 
2017-09-26 14:30:07.691884+0800 WCCTestProj[1714:89691] *** -[NSObject isProxy]: message sent to deallocated instance 0x600000012490

代码执行情况如下:

1.3.3 所有权修饰符_第3张图片

1.3.3 所有权修饰符_第4张图片

在使用 __unsafe_unretained修饰符时,赋值给附有 __strong修饰符的变量时有必要确保被赋值的对象确实存在。

__autoreleasing修饰符

1.3.3 所有权修饰符_第5张图片
屏幕快照 2017-09-26 14.38.52.png
1.3.3 所有权修饰符_第6张图片

1.3.3 所有权修饰符_第7张图片
1.3.3 所有权修饰符_第8张图片
屏幕快照 2017-09-26 14.51.32.png
1.3.3 所有权修饰符_第9张图片
1.3.3 所有权修饰符_第10张图片
1.3.3 所有权修饰符_第11张图片
1.3.3 所有权修饰符_第12张图片

自己测试的结果:

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) 
1.3.3 所有权修饰符_第13张图片

你可能感兴趣的:(1.3.3 所有权修饰符)