在释放的对象上调用方法

时间:2010-11-25 21:28:56

标签: objective-c cocoa

我认为我对内存管理缺少一些东西。这是代码:

NSString *string = @"foo";
[string release];
NSLog(@"%@", string);

我希望使用该代码获得内存错误,但代码运行时没有错误。我注意到这一点,因为我正在关注一本书,并且在设置属性和添加子视图之前发布了scrollView(但是在插入主视图之后)。

我的问题是,什么时候对象真的被解除分配?这会被认为是好的编码风格吗?

3 个答案:

答案 0 :(得分:5)

这是有效的,因为您的string变量指向已编译到应用程序中的常量字符串。 retain它没有做任何事情release它也没有做任何事情。它存在于静态内存中,只有在从内存中卸载程序时才会销毁它。

答案 1 :(得分:3)

如果您分配,保留或复制对象,则您有责任将其释放。其他所有内容都由系统处理,并将使用自动释放池刷新。

已经有太多关于SO的内存管理问题了,快速了解一下让自己熟悉https://stackoverflow.com/search?q=memory+management+iphone

[编辑] 你需要理解的问题中最重要的部分可能是你的第二段:

I was following a book and a scrollView was released before setting properties and adding a subView (but after being inserted in the main view).

我还没有看到这段代码,但很可能是你将scrollView添加到你的UIView实例中。在这些情况下,接收视图始终保留其子视图,以便您可以自由发布它。

一旦发布UIView实例,它还会向其所有子视图发送一条发布消息,其中包括scrollView。

有道理吗?

答案 2 :(得分:3)

向解除分配的对象发送消息是未定义的行为。您可能会收到内存错误,最终可能会向另一个对象发送消息,您最终可能会将消息发送到前一个对象的幻像版本 - 这一切都取决于实施细节和运行时环境的详细信息你无法控制。在这种特定情况下,您将遇到NSString常量不朽的实现细节。

特别是当对象将被释放时,这也是一个实现细节。如果你没有一个对象并且没有合理的保证它仍然存在(例如你只是通过[someArrayYouOwn objectAtIndex:0]得到它),你就不应该处理它。

最佳政策:只是不要向您不再拥有的对象发送消息。遵循内存管理规则。