大量Objective-C类返回对象。例如,[[instanceOfNSWhatever objectForKey:aKey] stringValue]
等语句遍及我(并希望其他所有人的代码)。
我应该如何记忆管理这些“中级”物品?
[instanceOfNSWhatever stringValue]
一百万次怎么办?我可以根据需要处理所有NSString
吗?我还在学习ObjC,虽然我一直善于平衡我的保留计数,但我对这些方法的工作方式缺乏了解。任何人都可以填写我吗?
答案 0 :(得分:7)
您可能已经阅读了Apple关于内存管理的文档的这一部分,但我会指出有关Object Ownership Policy的部分,以防万一。您只负责管理您“拥有”的对象的内存。引用文档:
- 您拥有自己创建的任何对象。
- 使用名称以“alloc”或“new”开头或包含“copy”的方法“创建”对象(例如,alloc,newObject或mutableCopy)。
- 如果您拥有某个对象,则您有责任在完成所有权后放弃所有权。 [即:发布]
- 如果您不拥有某个对象,则不得将其释放。
这些文档的“简单示例”部分提供了很好的阐述,但是要将上述要点放在特定问题的上下文中:
我应该如何记忆管理这些“中级”物品?
好消息是:你没有。忽略示例中“中间”对象的内存管理方面。
- 他们刚刚创建或者他们是否一直存在?
它们可能一直存在,或者它们可能刚刚被创建。 Objective-c的美妙之处在于,作为这些物体的消费者,您无需关心。
- 我可以保留它们,如果我释放创建它们的对象,它们也会被释放吗?
如果您只是将它们传递给其他函数,或者在函数内自己的计算中将它们用作中间值,则不需要保留它们。例如,假设您将示例函数中的stringValue
返回给其他人。保留它只是为了让它回归是没有意义的。
如果你碰巧保留它,那么是的,你有责任发布相应的发布消息。例如,如果您希望将该值保留为您自己实例中的属性,则可以保留示例中的stringValue
。 Objective-C使用引用计数。如果你需要长时间保持该对象,你必须保留它,以便在保留计数降至0时,其他人的释放消息不会导致它消失。
他们是自动释放的吗?
取决于。假设您要求instanceOfNSWhatever
的字符串。如果instanceOfNSWhatever
必须为您创建特殊的字符串(为了服务您的请求),但是不关心该字符串,那么是... instanceOfNSWhatever
可能将该字符串放入自动释放池。如果该字符串已经是instanceOfNSWhatever
的属性,并且它只是发送给您以响应您的请求,那么不,它可能没有自动释放。
再次,美丽是:你不知道也不需要关心。由于instanceOfNSWhatever
创建了字符串,因此它负责管理它。除非通过向字符串发送保留消息来添加字符串,否则可以忽略内存管理。
如果我在循环中运行[instanceOfNSWhatever stringValue]一百万次怎么办?我可以根据需要处理所有这些NSStrings吗?
没有必要。再次...... stringValue
不是你要管理的,因为你没有创建它。作为技术说明,如果instanceOfNSWhatever
确实需要创建100万份stringValue
来为您的100万次调用提供服务,那么它可能会将它们全部放入自动释放池中,这将在最后当前的可可事件循环。幸运的是,除非您向每个stringValue
个对象发送保留消息,否则您可以在这里兴高采烈地忽略内存管理问题。
答案 1 :(得分:5)
您基本上根据Memory Management Programming Guide for Cocoa管理所有内存。但是,简而言之,您基本上只需要担心“拥有”的对象。如果你创建了一个对象,你就拥有了一个对象(在Cocoa中,你通过使用alloc
专门分配它或者使用copy
或它们的衍生物之一来复制它来创建一个对象)。如果您拥有一个对象,那么当您完成它时,您有责任释放它。
因此,任何其他对象不归您所有。如果您需要在任何延长的时间段内使用此类对象(例如,在您收到它的范围之外),您需要通过发送retain
消息或复制它来专门获取对象的所有权。
要回答上一个问题,如果要以循环或其他方式创建大量临时对象,则可以创建自己的自动释放池。有关使用它们的更多信息,请参阅NSAutoreleasePool的documentation。但是,请注意,在对应用程序进行概要分析后发现它使用了太多内存并从这种优化中受益时,您应该只执行此操作。
最后,如果您正在创建和发布大量重物并且不想依赖自动释放池,您可以专门分配和初始化它们,然后确保一旦您自己发布它们就自己发布它们完成了他们。大多数具有便利创建者的对象具有类似的初始化器,用于专门创建对象。
答案 2 :(得分:2)
使用iPhone / iPod Touch时,应用程序退出时会释放自动释放对象。这可能是你不想要的。特别是在处理图像或大块数据时。为了确保标记为自动释放的大型内存池能够更快地发布,请创建本地自动释放池。像这样:
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
-- do something that creates large autorelease memory blocks --
[localPool drain];
如果您不这样做,您会发现您的应用程序意外退出。
答案 3 :(得分:1)
我会告诉你一个简单的规则,我希望在我第一次开始使用Objective-C时就知道了。)
这几乎涵盖了您需要了解的内存管理基础知识。
ObjC大量使用所谓的“自动释放”池。从非alloc / copy函数返回的对象将放入这些池中,并在函数存在后自动释放。
这就是为什么你不需要发布类似[obj stringValue]的结果。