weak retain strong assign

2018-04-20  本文已影响5人  05fad25aea68

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

指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。
注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。

retain的实际语法为:

- (void)setName:(NSString *)newName { 
      if (name != newName) { 
            [name release]; 
            name = [newName retain]; 
            // name’s retain count has been bumped up by 1 
      } 
}

也就是说,retain是指针拷贝,copy是内容拷贝。

assign: 简单赋值,不更改索引计数

NSString *pt = [[NSString alloc] initWithString:@"abc"];
上面一段代码会执行以下两个动作

在堆上分配一段内存用来存储@"abc" 比如:内存地址为:0X1111 内容为 "abc"
在栈上分配一段内存用来存储pt 比如:地址为:0Xaaaa 内容自然为0X1111
下面分别看下assign retain copy

assign的情况:NSString *newPt = [pt assing];
此时newPt和pt完全相同 地址都是0Xaaaa 内容为0X1111 即newPt只是pt的别名,对任何一个操作就等于对另一个操作。 因此retainCount不需要增加。

retain的情况:NSString *newPt = [pt retain];
此时newPt的地址不再为0Xaaaa,可能为0Xaabb 但是内容依然为0X1111。 因此newPt 和 pt 都可以管理"abc"所在的内存。因此 retainCount需要增加1

copy的情况:NSString *newPt = [pt copy];
此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@"abc 同时会在栈上为newPt分配空间 比如地址:0Xaacc 内容为0X1122 因此retainCount增加1供newPt来管理0X1122这段内存

实验验证


image.png image.png

实验结果:assign一个对象,并不是别名。不增加引用计数的一个指针。

ps.用NSStirng做实验不行,编译器对常量也有优化
1.首先我们可以看到通过 NSString 的手动引用的计数发现是一个非常巨大的数字,这也反映出平时所用的计数方法对于字符串并不适用,并且通过 retain 和 release 方法也不会改变其计数
2.其次通过打印的字符串对象的地址,我们也可以发现,并不是每次都会创建出一个新的对象,通过相同方法创建出来的相同内容的字符串对象地址相同,也就说明他们其实是同一个对象
 因此,这也说明,字符串在 OC 中系统对其有特殊的处理方式,当字符串创建出来时会放到一个固定的代码块,如果之后创建出来的字符串对象内容是相同的,会将后创建的字符串也指向那个字符串

发现一个新问题。:这里用的TestViewController,换成一个自定义的对象,MyNSObject,什么都不写。每次结果都对。 但是如果用TestViewController的话,一直点击测试按钮,会不断出现3的情况,如图:


image.png

用一个空白的ViewController找到了原因,在ARC内存分配和释放,猜测有优化和延迟。(查找copy生成的新对象地址,竟然在几次执行中 都是同一地址!测试按钮点击多次,每次都是对临时变量pt的对象BlankView进行复制,地址为什么会出现一样的。而且从打印看,复制的对象调用了dealloc已经释放了。为什么还会出现3??暂时猜测对UIViewController的复制和释放有优化
1.因为自定义一个MyNSObject测试 则不会出现这个问题。
2.点击测试按钮多次,日志栏搜索copy生成的对象,它的地址出现多次。利用之前的对象。注意:是已经释放的对象地址!!!或许只是释放了,所以重新利用。暂时的瞎猜)


image.png
2018-04-20 14:18:19.937790+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:19.937939+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:19.938092+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:19.938323+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:19.938444+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:19.938600+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:19.938734+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd05691b710, 指向对象值:<BlankViewController: 0x7fd05691b710>, --> pt
2018-04-20 14:18:19.938826+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd05691b710, 指向对象值:<BlankViewController: 0x7fd05691b710>, --> assign
2018-04-20 14:18:19.938911+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd05691b710, 指向对象值:<BlankViewController: 0x7fd05691b710>, --> retain
2018-04-20 14:18:19.939021+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd054506540, 指向对象值:<BlankViewController: 0x7fd054506540>, --> copy
2018-04-20 14:18:21.466920+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:21.467218+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:21.467442+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:21.467830+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:21.468061+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:21.468292+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:21.468442+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> pt
2018-04-20 14:18:21.468573+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> assign
2018-04-20 14:18:21.468704+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> retain
2018-04-20 14:18:21.468799+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd05450a1d0, 指向对象值:<BlankViewController: 0x7fd05450a1d0>, --> copy
2018-04-20 14:18:22.491260+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:22.491523+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:22.491755+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:22.492071+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:22.492242+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:22.492463+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:22.492585+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd054418db0, 指向对象值:<BlankViewController: 0x7fd054418db0>, --> pt
2018-04-20 14:18:22.492729+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd054418db0, 指向对象值:<BlankViewController: 0x7fd054418db0>, --> assign
2018-04-20 14:18:22.492861+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd054418db0, 指向对象值:<BlankViewController: 0x7fd054418db0>, --> retain
2018-04-20 14:18:22.492995+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd05691b710, 指向对象值:<BlankViewController: 0x7fd05691b710>, --> copy
2018-04-20 14:18:24.176296+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:24.176514+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:24.176671+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:24.176887+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:24.177063+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:24.177262+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:24.177432+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> pt
2018-04-20 14:18:24.177582+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> assign
2018-04-20 14:18:24.177718+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd0545088c0, 指向对象值:<BlankViewController: 0x7fd0545088c0>, --> retain
2018-04-20 14:18:24.177838+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd054506540, 指向对象值:<BlankViewController: 0x7fd054506540>, --> copy
2018-04-20 14:18:25.216241+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:25.216427+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:25.216571+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:25.216782+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:25.217004+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:25.217236+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:25.217378+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd054720a90, 指向对象值:<BlankViewController: 0x7fd054720a90>, --> pt
2018-04-20 14:18:25.217474+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd054720a90, 指向对象值:<BlankViewController: 0x7fd054720a90>, --> assign
2018-04-20 14:18:25.217583+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd054720a90, 指向对象值:<BlankViewController: 0x7fd054720a90>, --> retain
2018-04-20 14:18:25.217705+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd054418db0, 指向对象值:<BlankViewController: 0x7fd054418db0>, --> copy
2018-04-20 14:18:26.056696+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:26.056952+0800 testGroupRead[15452:5130626] pt 引用计数 = 1

2018-04-20 14:18:26.057162+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:26.057446+0800 testGroupRead[15452:5130626] pt 引用计数 = 2

2018-04-20 14:18:26.057714+0800 testGroupRead[15452:5130626] BlankViewController dealloc
2018-04-20 14:18:26.057973+0800 testGroupRead[15452:5130626] pt 引用计数 = 3

2018-04-20 14:18:26.058151+0800 testGroupRead[15452:5130626] 变量内存地址:0x7ffee30790c0, 变量值:0x7fd054419100, 指向对象值:<BlankViewController: 0x7fd054419100>, --> pt
2018-04-20 14:18:26.058305+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a260, 变量值:0x7fd054419100, 指向对象值:<BlankViewController: 0x7fd054419100>, --> assign
2018-04-20 14:18:26.058449+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a268, 变量值:0x7fd054419100, 指向对象值:<BlankViewController: 0x7fd054419100>, --> retain
2018-04-20 14:18:26.058589+0800 testGroupRead[15452:5130626] 变量内存地址:0x7fd05440a270, 变量值:0x7fd054506540, 指向对象值:<BlankViewController: 0x7fd054506540>, --> copy
上一篇 下一篇

猜你喜欢

热点阅读