ios – 为什么我可以将消息发送到NSArray的解除分配的实例?

ios – 为什么我可以将消息发送到NSArray的解除分配的实例?,第1张

概述我刚刚注意到NSArray的一个令人惊讶的行为,这就是我发布这个问题的原因. 我刚刚添加了一个方法: - (IBAction) crashOrNot{ NSArray *array = [[NSArray alloc] init]; array = [[NSArray alloc] init]; [array release]; [array release];} 从理 我刚刚注意到NSArray的一个令人惊讶的行为,这就是我发布这个问题的原因.

我刚刚添加了一个方法:

- (IBAction) crashOrNot{   NSArray *array = [[NSArray alloc] init];   array = [[NSArray alloc] init];   [array release];   [array release];}

从理论上讲,这段代码会崩溃.但在我的情况下它永远不会崩溃!

我用NSMutableArray更改了NSArray,但这次应用程序崩溃了.
为什么会发生这种情况,为什么NSArray没有崩溃而NSMutableArray崩溃了?

解决方法 通常,当您释放一个对象时,内存不会被清零,只需要任何需要它的人都可以自由地回收它.因此,如果保留指向解除分配对象的指针,通常仍可以使用该对象一段时间(就像使用第二次发布消息一样).示例代码:
#import <Foundation/Foundation.h>@interface Foo : NSObject@property(assign) NSUInteger canary;@end@implementation Foo@synthesize canary;@endint main(int argc,const char * argv[]){    @autoreleasepool {        Foo *foo = [[Foo alloc] init];        [foo setCanary:42];        [foo release];        NSLog(@"%li",[foo canary]); // 42,no problem    }    return 0;}

默认情况下没有对此进行检查,行为很简单.如果设置NSZombIEEnabled环境值,消息传递代码将开始检查已释放的对象,并应在您的情况下抛出异常,就像您可能期望的那样:

*** -[Foo canary]: message sent to deallocated instance 0x100108250

顺便说一下,默认的,未经检查的情况是内存错误难以调试的原因之一,因为行为可能是非常不确定的(它取决于内存使用模式).您可能会在代码周围出现奇怪的错误,而错误是在其他地方过度释放的对象.继续上一个例子:

Foo *foo = [[Foo alloc] init];[foo setCanary:42];[foo release];Foo *bar = [[Foo alloc] init];[bar setCanary:11];NSLog(@"%li",[foo canary]); // 11,magic! (Not guaranteed.)

至于为什么NSArray与NSMutableArray不同,一个空数组看起来确实像一个特殊的野兽:

NSArray *foo = [[NSArray alloc] init];NSArray *bar = [[NSArray alloc] init];NSLog(@"%i",foo == bar); // yes,they point to the same object

所以这可能与它有关.但在一般情况下,使用解除分配的对象可能会做任何事情.它可能会起作用,也可能不起作用,它可能会泄漏你的咖啡或开始核战争.不要这样做.

总结

以上是内存溢出为你收集整理的ios – 为什么我可以将消息发送到NSArray的解除分配的实例?全部内容,希望文章能够帮你解决ios – 为什么我可以将消息发送到NSArray的解除分配的实例?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1109212.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存