-->

代码示例:为什么我仍然可以访问这个对象NSString的我已经发布了它?(Code Example:

2019-07-21 05:12发布

我只是写一些探索性的代码来巩固我的Objective-C的理解和我碰到这个例子中,我没有完全得到来了。 我定义这个方法并运行代码:

- (NSString *)stringMethod
{
    NSString *stringPointer = [[NSString alloc] initWithFormat:@"string inside stringPointer"];
    [stringPointer release];
    [stringPointer release];
    NSLog(@"retain count of stringPointer is %i", [stringPointer retainCount]);
    return stringPointer;
}

运行代码,调用此方法后,我注意到一些事情:

  1. 通常情况下,如果我尝试访问东西是打零保留计数后按说dealloced,我得到一个EXC_BAD_ACCESS错误。 在这里,我得到一个malloc“双免费”错误信息。 这是为什么?

  2. 不管如何“[stringPointer发行]”多行我添加到代码中,报告的NSLog当我添加更多的释放一个保留1计数我只是得到更多的“双无”的错误。 为什么没有按预期工作发布声明?

  3. 虽然我已经过发布stringPointer和我收到了一堆的“双无”的错误,返回值仍然有效,仿佛什么都没有发生(我有另一种的NSLog在报告返回值的主代码)。 该计划将继续正常运行。 同样,有人可以解释为什么出现这种情况?

这些例子是相当琐碎,但我试图让这是怎么回事十足的把握。 谢谢!

Answer 1:

你得到一个双无错,因为你释放两次,使两个的dealloc消息。 = P

请,只是因为你释放不并不意味着其在内存地址中的数据被立即销毁头脑。 它使内核知道,在未来的某个时刻,它是免费使用的另一块数据只是被标记为未使用。 在那之前(这是在你的应用空间完全不确定的),则数据将保留在那里。

所以,再一次:释放(和dealloc'ing)在字节级不立即必要的数据销毁。 这只是为内核的标记。



Answer 2:

有几件事情会在这里的。 首先,deallocing的对象不一定清除任何对象以前所占用的内存。 它只是将其标记为免费。 除非你做别的事情了导致被重新使用的内存,旧的数据只会流连。

在的NSString的特定情况下,它是一类集群,这意味着你从分配/初始化回到实际的类的NSString的一些具体子类,而不是一个NSString实例。 对于“恒定”的字符串,这是仅仅保持一个指向C-字符串常量极轻量的结构。 不管你如何将其释放后striing你做,或者有多少次的多个副本,你会不会影响指针常数C字符串的有效性。

尝试检查在这种情况下,[stringPointer类],以及在一个可变的字符串,或实际使用的格式字符和参数的格式化字符串的情况下。 也许所有这三个会变成有不同的类。



Answer 3:

该retainCount始终打印一个可能是造成优化 - 当释放注意到它要被释放,没有理由更新retainCount为零(在这一点上没有人应具有对对象的引用),并替代更新retainCount刚刚解除分配。



文章来源: Code Example: Why can I still access this NSString object after I've released it?