为啥在调试模式和运行模式下保留计数不同?
Posted
技术标签:
【中文标题】为啥在调试模式和运行模式下保留计数不同?【英文标题】:Why retain count is diffrent in debug mode and in running mode?为什么在调试模式和运行模式下保留计数不同? 【发布时间】:2016-05-12 08:49:35 【问题描述】:我知道 ARC 和 MRC 的工作原理。但是在测试下面的代码时我很困惑。我不知道为什么会这样。为什么同一个问题在调试模式和运行模式下保留计数不同?
NSMutableArray *a = [NSMutableArray array];
[a addObject:@"abc"];
NSLog(@" 1 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)a));
__weak NSMutableArray *b = a;
NSLog(@" 2 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)a));
a = nil;
NSLog(@" 3 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)b));
[b addObject:@"xys"];
NSLog(@" 4 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)b));
当我在运行模式下运行应用程序时,应用程序在行 NSLog(@" 3 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)b));
上崩溃,我理解为 b 是 a 的 weak
引用。并在将nil
分配给它时反对获取释放。但在此之前,如果显示前两行的输出如下图所示。这也是正确的。
但是当应用程序处于调试模式时(意味着我们已经设置了断点和调试),应用程序没有崩溃,并且在每行显示保留计数 2。如下图。
有人知道为什么会这样吗?为什么相同的代码为不同的模式给出两个不同的保留值?
【问题讨论】:
不要依赖retainCount 做任何事情。尤其是使用 ARC,您无法分辨retain
s 和 release
s 插入的位置。在发布模式下,优化器会尽量避免无关的retain
s 和release
s,所以你看到的数字通常会不同。
天哪。接力棒!
【参考方案1】:
documentation 中 retainCount
方法的第一句话说:
请勿使用此方法。
后来:
您不太可能从这种方法中获得有用的信息
只是不要使用它。
正如 ***foe 在评论中指出的那样,给定代码中使用的 CFGetRetainCount 有一个类似的(可能稍微少一些)免责声明。
我一直将其理解为“它可能有用,但价值可能不是您认为的那样。不要通过查看绝对值得出任何结论,因为我们可能会做我们想做的每一个魔术有了它,这不关你的事”。
【讨论】:
而CFGetRetainCount()
(OP实际使用的方法)的文档说“这个函数可能对调试内存泄漏有用。你通常不使用这个函数,否则。”。
是的,我知道我们不应该使用这种方法。但我的观点是这种方法有什么问题。为什么它提供错误的 retainCount ?
应该没有错。但是可能会有比您想象的更多(或更少)的保留或发布。由于编译器所做的优化,它们也可能在不同的时间发生。然后,谁知道调试模式会发生什么变化?但我同意,这种语义变化似乎很奇怪!以上是关于为啥在调试模式和运行模式下保留计数不同?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的程序在发布模式下运行良好,但在调试模式下失败? [关闭]