美文网首页iOS plus
Property中的Strong、Assign、Weak、Cop

Property中的Strong、Assign、Weak、Cop

作者: 董二千 | 来源:发表于2016-01-05 23:51 被阅读193次

现在发现有些东西,即使当时懂了,用的时候有会很模糊,还是需要自己写下来,慢慢总结才行

这里不能用NSString类型来测试苹果对它进行过优化。下面大家主要看*obj这个对象的地址,另外一个地址我暂时也不清楚是什么地址

Strong

强引用,对象的引用计数器值+1

@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, strong) TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:s2 = <TestObj:0x7f97a9c73740>;
内存:前:_s1: 0x7f97a9fa0118 *_s1: 0x7f97a9c73740; _s2: 0x7f97a9fa0120 *_s2: 0x7f97a9c73740
     后:_s1: 0x7f97a9fa0118  *_s1: 0x0;         _s2: 0x7f97a9fa0120 *_s2: 0x7f97a9c73740
可见,s1指向的地址中的内容已经不存在了,但是因为引用计数+1了所以该块内存不会被释放,可以继续访问

Assign

弱引用,对象的引用计数器值不变,用于基础类型(基础类型copy,基础类型没有引用计数的概念)

@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, assign) TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:crash  但是打印出了s2 = 0x7fb668419500 (这里有时候会crash,有时候不会,当这块地址被回收了,就会crash。因为s1和s2指向同一块地址,当s1被释放了,地址就极可能会被回收。)
内存:前:_s1: 0x7fb66871ca28 *_s1: 0x7fb668419500;  _s2: 0x7fb66871ca30 *_s2: 0x7fb668419500
     后:_s1: 0x7fb66871ca28  *_s1: 0x0;         _s2: 0x7fb66871ca30 *_s2: 0x7fb668419500
可见,s1指向的地址已经被回收,所以s2找不到地址。

Weak

弱引用,如果持有对象被释放,该对象也自动释放

@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, weak)   TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:s2 = nil;
内存:前:_s1: 0x7f968973a888 *_s1: 0x7f9689554460;  _s2: 0x7f968973a890 *_s2: 0x7f9689554460
     后:_s1: 0x7f968973a888  *_s1: 0x0;         _s2: 0x7f968973a890 *_s2: 0x0
可见,s1的内存地址被回收,s2的指针也变成nil,不会再指向该地址

Copy

拷贝一份

//对象要实现NSCopy协议
@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, copy)   TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:s2 = <TestObj:0x7fdaf1f54300>;
内存:前:_s1: 0x7fdaf1d935f8 *_s1: 0x7fdaf1f543e0;  _s2: 0x7fdaf1d93600 *_s2: 0x7fdaf1f54300
     后:_s1: 0x7fdaf1d935f8  *_s1: 0x0;         _s2: 0x7fdaf1d93600 *_s2: 0x7fdaf1f54300
可见,s1、s2指针指向的地址是不同的因为copy了一份,内容相同,不是原来的地址了,所以s1= nil,不影响s2

Retain

释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为+1

@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, retain)   TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:s2 = <TestObj:0x7fdaf1f54300>;
内存:前:_s1: 0x7ffb5872cc78 *_s1: 0x7ffb5875c1b0;  _s2: 0x7ffb5872cc80 *_s2: 0x7ffb5875c1b0
     后:_s1: 0x7ffb5872cc78  *_s1: 0x0;         _s2: 0x7ffb5872cc80 *_s2: 0x7ffb5875c1b0
可见,s1、s2指针指向的地址是相同的,所以s1= nil,不影响s2。因为引用+1了,所以该内存地址不会被回收

** unsafe_unretained**

和assign类似,但是它适用于对象类型,当目标被摧毁时,属性值不会自动清空(unsafe)。这是和weak的区别

@property (nonatomic, strong) TestObj *s1;
@property (nonatomic, unsafe_unretained)  TestObj *s2;
self.s1 = [[TestObj allow] init];
self.s2 = self.s1;
self.s1 = nil;
NSLog(@"s2 = %@",self.s2);
结果:crash;
内存:前:_s1: 0x7fd5dbf7f698 *_s1: 0x7fd5dbfa42f0;  _s2: 0x7fd5dbf7f6a0 *_s2: 0x7fd5dbfa42f0
     后:_s1: 0x7fd5dbf7f698  *_s1: 0x0;         _s2: 0x7fd5dbf7f6a0 *_s2: 0x7fd5dbfa42f0
可见,s1、s2指针指向的地址是相同的,s1=nil,让该块地址被回收,当s2指向这个地址时,就会找不到

相关文章

网友评论

    本文标题:Property中的Strong、Assign、Weak、Cop

    本文链接:https://www.haomeiwen.com/subject/vdezhttx.html