今天小伙伴在群里讨论view在xib上removeFromSuperview之后会不会被释放产生了歧义
注:imageView是IBOutlet,ARC下是weak,MRC下强制要写成strong
在ARC模式下
//打印结果 retainCount 3
NSLog(@" retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)self.ImageView));
[self.ImageView removeFromSuperview];
//打印结果 removeFromSuperview retainCount 3
NSLog(@" removeFromSuperview retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)self.ImageView));
[self.ImageView removeFromSuperview];
//打印结果 removeFromSuperview22222222 retainCount 4(打印结果不准确)
NSLog(@" removeFromSuperview22222222 retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)self.ImageView));
[self.view addSubview:self.ImageView];
//打印结果 addSubview retainCount 5
NSLog(@" addSubview retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)self.ImageView));
[self.view addSubview:self.ImageView];
//打印结果 addSubview2222222 retainCount 5
NSLog(@" addSubview2222222 retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)self.ImageView));
图为打印结果:
执行removeFromSuperview方法后,会从父视图中移除,并且将Superview对视图的强引用删除,此时如果没有其他地方再对视图进行强引用,则会从内存中移除。如果还存在其他强引用,视图只是不在屏幕中显示,并没有将该视图从内存中移除。所以如果需要使用该视图,不需要再次创建,而是直接addSubview就可以了。
切换MRC模式:项目—>project—>build Setting—>搜Automatic Reference
对象销毁的标志:retainCount是否为0,只有release 才会造成引用计数-1 所以在MRC模式下,在项目不崩溃的情况下最多使用几次release,那么当时的引用计数就为几(因为引用计数有时候不准确,所以只能这样了~~~)
当视图存在的时候removeFromSuperview 不会使引用计数+1
当视图不存在的时候removeFromSuperview 引用计数不准确
打印结果 removeFromSuperview22222222 retainCount 4(打印结果不准确)
在MRC中,根据官方API的说明:
If the view’s superview is not nil, the superview releases the view.
也就是每执行一次removeFromSuperview方法,方法内部都会执行一次release操作。但是经过我的测试,发现调用removeFromSuperview方法后,引用计数并没有减少,反而增加了一个。 所以我们就可以在MRC下使用[self.imageView release]查看一下
我们之前看到的引用计数的增加,是因为系统的隐藏操作导致的。之前在MRC时期经常发现retainCount不准确,这主要是因为iOS系统API的引用、或自动释放池导致的,所以retainCount并不能当做可靠的参考。
所以,如果调用多个release,还是会崩溃的,始终要相信iOS的MRC内存管理原则,这才是可靠的。可以多次调用removeFromSuperview方法,在已经移除父视图后,其他多余的调用不会改变任何引用计数。 对于addSubview:方法也是一样的
当视图不存在的时候addSubview 会使引用计数+1
当视图存在的时候addSubview 不会使引用计数+1
参考链接 博主比我思路清晰可以参考他的这篇文章