Objective c 我应该如何管理实例方法返回的对象?
很多Objective-C类返回对象。例如,像Objective c 我应该如何管理实例方法返回的对象?,objective-c,cocoa,Objective C,Cocoa,很多Objective-C类返回对象。例如,像[[instanceOfNSWhatever-objectForKey:aKey]stringValue]这样的语句出现在我的代码中(希望每个人的代码中都有) 我应该如何管理这些“中间”对象的内存 它们是被创造出来的还是一直存在的 我可以保留它们吗?如果我释放创建它们的对象,它们也会被释放吗 它们是自动释放的吗 如果我在一个循环中运行[instanceOfNSWhatever stringValue]一百万次会怎么样?我可以根据需要处置所有这些NS
[[instanceOfNSWhatever-objectForKey:aKey]stringValue]
这样的语句出现在我的代码中(希望每个人的代码中都有)
我应该如何管理这些“中间”对象的内存
- 它们是被创造出来的还是一直存在的
- 我可以保留它们吗?如果我释放创建它们的对象,它们也会被释放吗
- 它们是自动释放的吗
- 如果我在一个循环中运行
一百万次会怎么样?我可以根据需要处置所有这些[instanceOfNSWhatever stringValue]
s吗NSString
我仍在学习ObjC,虽然我善于平衡我的总体保留计数,但我确实对这些方法的工作原理缺乏一些了解。有人能告诉我吗?你基本上是按照规则管理你所有的内存的。然而,简而言之,您基本上只需要担心您“拥有”的对象。如果您创建了一个对象,那么您就拥有了它(在Cocoa中,您通过使用
alloc
专门分配对象,或者使用copy
或其衍生工具复制对象来创建对象)。如果您拥有一个对象,那么您有责任在完成该对象后将其释放
因此,任何其他对象均不归您所有。如果您需要在任何延长期限内(例如,在您接收对象的范围之外)使用此类对象,您需要通过向其发送retain
消息或复制消息来明确获取对象的所有权
要回答上一个问题,如果要以循环或其他方式创建大量临时对象,可以创建自己的自动释放池。有关使用NSAutoreleasePool的更多信息,请参阅。但是,请注意,只有在您分析了应用程序并发现它使用了太多内存并且从这种优化中受益后,您才应该这样做
最后,如果您正在创建和释放大量重对象,并且不想依赖自动释放池,那么您可以专门分配和初始化它们,然后确保在使用完它们后立即自行释放它们。大多数具有方便创建者的对象都有类似的初始值设定项来专门创建对象。我将告诉您一个简单的规则,我希望我在第一次启动Objective-C时就知道这个规则:)
- 如果一个方法包含单词“alloc”或“copy”,那么您必须在完成时[释放]对象
- 如果一个方法不包含这些词,您必须[保留]它,以便它在您的函数之外保持有效
- 如果调用[retain],则必须在完成后调用[release]
这就是为什么您不需要发布类似于[obj stringValue]的结果。您可能已经阅读了苹果关于内存管理的文档的这一部分,但我将向您指出关于以防万一的部分。您只负责管理您“拥有”的对象的内存。引用文件:
- 您拥有您创建的任何对象
- 使用名称以“alloc”或“new”开头或包含“copy”的方法“创建”对象(例如,alloc、newObject或mutableCopy)
- 如果您拥有一个对象,您有责任在完成该对象后放弃其所有权。[即:释放]
- 如果您不拥有某个对象,则不能释放它
- 它们是被创造出来的还是一直存在的
- 我可以保留它们吗?如果我释放创建它们的对象,它们也会被释放吗
stringValue
返回给其他人。保留它只是为了归还它是没有意义的
如果您碰巧保留了它,那么是的,您有责任发布相应的发布消息。例如,如果希望在自己的实例中将该值作为属性保留,则可以保留示例中的stringValue
。Objective-C使用参考计数。如果需要该对象长时间保留,则必须保留该对象,以便在保留计数降至0时,其他人的释放消息不会导致该对象消失
它们是自动释放的吗
视情况而定。假设您从instanceOfNSWhatever
请求一个字符串。如果instanceOfNSWhatever
必须为您创建专门的字符串(为了满足您的请求),但不关心该字符串,那么是的instanceofnswhat
可能会将该字符串放入自动释放池。如果字符串已经是instanceOfNSWhatever
的属性,并且它只是响应您的请求将其发送给您,那么不,它可能没有自动删除
同样,美在于:你不知道也不知道
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
-- do something that creates large autorelease memory blocks --
[localPool drain];