大量的Objective-C类返回对象.[[instanceOfNSWhatever objectForKey:aKey] stringValue]
例如,像我这样的陈述(希望是其他人的代码).
我该如何记忆管理这些"中间"对象?
他们刚刚创建或者他们是否一直存在?
我可以保留它们吗?如果我释放创建它们的对象,它们也会被释放吗?
他们是自动释放的吗?
如果我[instanceOfNSWhatever stringValue]
在一个循环中运行一百万次怎么办?我可以NSString
根据需要处理所有这些吗?
我还在学习ObjC,虽然我一直善于平衡我的保留计数,但我对这些方法的工作原理缺乏了解.任何人都可以填写我吗?
您可能已经阅读了Apple关于内存管理的文档的这一部分,但为了以防万一,我将向您介绍有关对象所有权策略的部分.您只负责管理您"拥有"的对象的内存.引用文档:
您拥有自己创建的任何对象.
使用名称以"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
对象发送保留消息,否则您可以兴高采烈地忽略此处的内存管理问题.
您基本上根据Cocoa的内存管理编程指南管理所有内存.但是,简而言之,您基本上只需要担心"拥有"的对象.如果你创建了一个对象,你就拥有了一个对象(在Cocoa中,你通过使用alloc
或使用copy
它们的衍生物之一专门分配它来创建一个对象).如果您拥有一个对象,那么当您完成它时,您有责任将其释放.
因此,任何其他对象不归您所有.如果您需要在任何延长的时间段内使用此类对象(例如,在您收到它的范围之外),您需要通过发送retain
消息或复制它来专门获取对象的所有权.
要回答上一个问题,如果要以循环或其他方式创建大量临时对象,则可以创建自己的自动释放池.有关使用它们的更多信息,请参阅NSAutoreleasePool 的文档.但是,请注意,在对应用程序进行概要分析后发现它使用了太多内存并从这种优化中受益时,您应该只执行此操作.
最后,如果您正在创建和发布大量重物并且不想依赖自动释放池,您可以专门分配和初始化它们,然后确保在完成它们后立即自行释放它们.大多数具有便利创建者的对象具有类似的初始化器,用于专门创建对象.