NSObject被释放,NSString和NSArray没有被释放?

5
如果我写 -
NSObject *a = [[NSObject alloc] init]; // or UIView or something
[a release];
NSLog(@"a = %@", a); // causes EXC_BAD_ACCESS, fine

但是,如果我写下这样的代码 -

NSArray *a = [[NSArray alloc] init]; // or NSString or NSDictionary
[a release];
NSLog(@"a = %@", a); // no crash, prints empty array or string

为什么第二种情况不会导致错误访问,因为它已经被释放了?
1个回答

8

释放后访问对象不一定会立即导致应用程序崩溃。

请注意,即使您释放了对象,内存仍然存在一段时间,并保持相同的内容。只有在对象内存已被其他对象覆盖后才会崩溃。请注意,即使是被覆盖的内存,也不一定会崩溃。您只能获得一些非常奇怪的行为(例如,当对象是NSString时,它可能具有不同的内容)。

基本上,这种行为是完全随机的。使用已释放的对象可能会立即导致应用程序崩溃,也可能是5分钟或2小时后。

编辑: 感谢Martin R提供有趣的评论。看起来,由[[NSArray alloc] init]创建的数组,即空不可变数组,总是返回相同的实例。这意味着您的release不会使其被解除分配。但是,这种行为很容易改变,可能因编译器或操作系统版本而异。


但是释放NSObject或UIView等肯定会立即崩溃,而释放NSArray或NSString等肯定不会立即崩溃。因此,在数组或字符串的内存使用、释放情况上肯定存在一些差异。那是什么? - user1559227
请参见 random。在这种情况下,它会崩溃 NSObject,但不会崩溃 NSArray。如果您使用不同的选项进行编译,它可能不会以那种方式运行。操作系统如何使用内存取决于许多因素。这就是 releaseddeallocated 之间的区别。 - borrrden
6
区别在于在第二种情况下,您会获得一个共享实例,该实例根本不会被释放,可以参考https://dev59.com/0XHYa4cB1Zd3GeqPNZ_r#16324350。 - Martin R
@MartinR 比我更清楚哈哈。我之前以为这个方法(叫做飞轮法)只适用于NSString、NSNumber等数据类型。 - borrrden
是的,就是这样。嗯,我想知道为什么我记错了(思考汽车发动机太多了?o,0) - borrrden
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接