【问题标题】:NSObject released, NSString, NSArray not?NSObject 发布了,NSString,NSArray 没有?
【发布时间】:2013-05-03 18:20:31
【问题描述】:

如果我写 -

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

为什么第二种情况不会导致错误访问,因为它已经发布了?

【问题讨论】:

    标签: ios objective-c memory-management


    【解决方案1】:

    访问已释放的对象不必立即使应用程序崩溃。

    请注意,即使您释放对象,内存也会在那里停留一段时间,内容相同。仅当对象内存已被其他对象覆盖时,您才会崩溃。请注意,即使内存被覆盖,您也不必崩溃。你只能得到一些非常奇怪的行为(例如当对象是NSString时,它可以得到不同的内容)。

    基本上,这种行为是完全随机的。使用释放的对象可以使您的应用程序立即或在 5 分钟或 2 小时内崩溃。

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

    【讨论】:

    • 你比我快,我本来想用同样的方式回答,结果一个字都没打出来。 +1
    • 但是释放 NSObject 或 UIView 等肯定会立即崩溃,而 NSArray 或 NSString 等肯定不会立即崩溃。所以内存使用,数组或字符串的释放情况必须存在一些差异。那是什么?
    • 参见随机。在这种情况下,NSObject 会崩溃,但 NSArray 不会。如果您使用不同的选项进行编译,它可能不会那样做。操作系统使用内存的方式因许多因素而异。这就是releaseddeallocated的区别
    • 不同之处在于第二种情况下你得到一个根本没有释放的共享实例,比较stackoverflow.com/questions/16323908/…
    • @MartinR 知道得更好哈哈。我以为这种方法(叫飞轮)只适用于 NSString、NSNumber 等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多