Iphone 未显式调用Objective-C release

Iphone 未显式调用Objective-C release,iphone,objective-c,cocoa,ios,Iphone,Objective C,Cocoa,Ios,输出:测试 为什么release不起作用? 如何立即从内存中删除对象 Xcode 4.0版iPhone应用程序 ~已解决~ 谢谢大家的回答。 关于这个问题,我有很多有用的信息。我将使用NSString*str=@“text”,而不是NSString*str=[[NSString alloc]initWithString:@“text]” 我知道,release只是将内存“标记”为“愿意释放”,但不是立即释放它,release确实可以工作,但您尝试执行的操作有未定义的行为,并且当使用NSStri

输出:测试

为什么
release
不起作用? 如何立即从内存中删除对象

Xcode 4.0版iPhone应用程序


~已解决~

谢谢大家的回答。 关于这个问题,我有很多有用的信息。我将使用NSString*str=@“text”,而不是NSString*str=[[NSString alloc]initWithString:@“text]”


我知道,release只是将内存“标记”为“愿意释放”,但不是立即释放它,release确实可以工作,但您尝试执行的操作有未定义的行为,并且当使用NSString和literal时,您也可能会得到不同的行为。发生的情况是,尽管对象被释放,但该位置的内存是可回收的,并且没有更改,当它打印时仍然有效。因为它是一个NSString,所以不一定要发送一条消息到描述,这就是为什么您在尝试向一个解除分配的对象发送消息时没有收到异常


有一些关于NSString和NSLog的好信息。

无需删除内存块,这将占用不必要的周期。
当为新对象分配了占用该内存块的内存时,该内存将被覆盖

确实有效。您已放弃该对象的所有权,当系统确定不再拥有该对象时,该对象将被标记为可供系统重用。如果您是字符串的唯一所有者,那么这种情况可能会立即发生。如果字符串的创建导致它在内部自动释放,则它可能会在稍后的某个点发生。或者,正如戴夫·德隆(Dave DeLong)所指出的,系统可能会将其优化为一个永远不会发布的对象

在您的例子中,它被优化为一个常量字符串,它将在程序的生命周期中存在。如果您使用
NSMutableString
而不是
NSString
,您将看到可能不会崩溃但不会打印您期望的内容的古怪行为。(有关示例,请参见。)

如果改用
NSArray
,则在调用
release
时,它将被解除分配,但在分配其他对象之前,您仍然可以看到NSLog示例正常工作。释放只是将内存标记为可重用;它实际上并没有把它弄清楚。因此,如果您将数组传递给NSLog,则该内存尚未更改,因此它仍然可以正确打印


然而,所有这些的关键点是要认识到调用
release
不一定会导致对象被释放。它可能会因为各种原因而继续存在。但一旦调用
release
,您就放弃了对象的所有权。如果您在这一点之后继续使用它,系统可以根据自己的意愿自由地做各种奇怪的事情,如所示。

您在NSLog()中使用了一个错误的指针。在这种情况下,您碰巧很幸运,但您应该预料到这样的代码会以其他方式崩溃或失败。

当您这样做时:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    

NSString * str = [[NSString alloc] initWithString:@"test"];
[str release];
int i = 999999999;
while(i-- > 0) {}
NSLog(@"%@", str);
[pool drain];
这将优化为:

NSString * str = [[NSString alloc] initWithString:@"test"];
您不能
释放
常量字符串,因为它是硬编码到应用程序二进制文件中的

证明:

NSString * str = @"test";
日志:


您可以看到
+alloc
的结果与
-initWithString:
的结果不同,并且
-initWithString:
的结果与常量字符串等效。基本上,
-initWithString:
说“啊哈,我将成为一个不可变的字符串,而我被赋予了一个不可变的字符串!我可以选择一个快捷方式,销毁自己,然后返回参数,一切都将保持不变”

这里到底有什么不起作用?@onnoweb他/她正在发布
str
,但仍然可以记录内容。@Joe-这并不意味着
-release
没有正常工作。即使在该对象上调用了
-dealloc
(如果给定一个用文本初始化的字符串,则不能保证这一点),这仅仅意味着它的内存被标记为可重用,而不意味着它一定已被重用。vaychick偶然发现了
NSString
的优化细节。仅此而已。当一条消息被发送到一个仍未在中重写的已释放对象时,objective c是否“有意”中止或警告您memory@Zaky-可以告诉它这样做,但是有很多开销,所以默认情况下它不会这样做。请看@Sherm ah是的,我知道NSZombie,我只是认为如果对象被释放,同样的行为可能会发生,但内存仍然“完整”+1,因为提到字符串文本可能会被不同的处理。使用+numberwhitint创建的NSNumber实例:有时可以以相同的方式运行,返回未释放的实例,而您可能会天真地假设。重要的是正确地平衡自己的内存管理——不要理会幕后的人老年退休金计划做到了这一点。因为我们关注的是实施细节……没有什么会破坏它自己
+[NSString alloc]
返回
NSPlaceholderString
的单例实例;所有
-[NSString init…]
方法都返回不同的对象。@XJones我不同意。问题是“为什么
release
不起作用?”,答案是“因为你不能释放一个常量字符串”。@XJones不,
release
不起作用,因为它没有达到OP预期的效果。他希望它能触发对
dealloc
的调用。但是,由于该字符串是常量,因此无法释放该字符串。我确实同意这是一个实现“细节”,但在问题的背景下,这是正确的答案。我发誓不会卷入关于密教的辩论,但我在这里。假设你100%正确。如果你建议他/她需要担心这一点,那你就是在给@vaychick一个伤害。问题不仅仅是为什么发布
NSString *s = [NSString alloc];
NSLog(@"%p", s);
s = [s initWithString:@"foo"];
NSLog(@"%p", s);
s = @"foo";
NSLog(@"%p", s);
2011-04-12 10:17:45.591 EmptyFoundation[6679:a0f] 0x100116370
2011-04-12 10:17:45.599 EmptyFoundation[6679:a0f] 0x100009270
2011-04-12 10:17:45.604 EmptyFoundation[6679:a0f] 0x100009270