Objective-C中的内存管理
Possible Duplicates: Learn Obj-C Memory Management Where are the best explanations of memory management for iPhone?
我来自C / C ++背景,Objective-C的动态性质对我来说有点陌生,是否有人可以为我提供一些很好的资源,以供我使用Objective-C中的一些基本内存管理技术?前任。保留,释放,自动释放
例如,使用指向Objective-C对象的指针并将其视为数组是完全违法的吗?我们是否被迫将NSArray和NSMutableArray用于数据结构?
我知道这些是相当新手的问题,感谢我们能为我提供的任何帮助。
解决方案
干得好:
Application memory management is the process of allocating memory during your program’s runtime, using it, and freeing it when you are done with it. A well-written program uses as little memory as possible. In Objective-C, it can also be seen as a way of distributing ownership of limited memory resources among many pieces of data and code. When you have finished working through this guide, you will have the knowledge you need to manage your application’s memory by explicitly managing the life cycle of objects and freeing them when they are no longer needed. Although memory management is typically considered at the level of an individual object, your goal is actually to manage object graphs. You want to make sure that you have no more objects in memory than you actually need...
如果是数组,请随时使用指针进行迭代。常规数组仍由C控制。如果它是NSArray,请阅读NSArray文档。如果他们说要以某种特定的方式进行操作,请以这种方式进行操作。为OS X编写代码时,请按书进行。
Objective-C只是C的超集。我们可以在C中做的任何事情在Objective-C中都是有效的。
我们当然可以使用数组并进行自己的内存管理。最大的组成部分是,如果要创建属于NSObject子类的任何东西,并使用[XXX alloc]方法创建它,或者如果我们使用[xxx copy]从另一个副本中获取它,则我们有责任将其与关联的发行版匹配。
如果从任何地方获取一个变量,并打算保留它的余地超过执行的立即使用量,则请确保对它调用[...保持]。
链接http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html包含所有详细信息,并且绝对是第一个阅读的地方。
注意,对于类消息,例如NSString +(NSString *)stringWithFormat :(基本上,是为我们分配对象而不是要求我们自己分配对象的帮助程序消息)的类消息,除非我们明确保留它。
规则如下:
- 如果通过调用alloc或者copy创建对象,则我们拥有该对象,并且必须在完成后释放它。
- 如果我们没有创建对象,但希望它能够确保控件在运行返回到运行循环之前一直存在(或者,为了简单起见,方法将返回),则向它发送一个"保留"消息,然后"释放"它。稍后,当我们完成时。
- 如果创建一个对象并想从方法中返回它,则有义务释放它,但是我们不想在调用者有机会看到它之前销毁它。因此,我们改为发送" autorelease",将其放入"自动释放池",一旦控制权返回程序的事件循环,该池将被清空。如果没有其他人保留该对象,则将其释放。
关于数组,我们可以随意执行以下操作:
NSObject *threeObjects[3]; threeObjects[0] = @"a string"; threeObjects[1] = [NSNumber numberWithInt:2]; threeObjects[2] = someOtherObject;
仍然使用NSArray的原因:
- 在添加对象时,NSArray会保留对象,而在删除对象时会释放对象,而在普通的C数组中,我们必须自己这样做。
- 如果将数组作为参数传递,则NSArray可以报告其包含的对象的数量,对于普通C数组,我们也需要传递一个数量。
- 在一行中混合使用方括号的含义感觉很奇怪:
[threeObjects [0] length]
重复内存管理的基本规则通常是没有用的,因为几乎总是会犯一个错误或者不完整地描述它们-就像'heckj'和'benzado'提供的答案一样。
Apple的"内存管理规则"文档中提供了内存管理的基本规则。
关于" www.stray-bits.com"的答案的一个恰当的说法:指出从"非拥有"方法返回的对象是"自动释放"的,这也充其量是令人误解的。通常,我们不应该考虑是否已"自动释放"某些东西,而只需考虑内存管理规则,并根据这些约定确定我们是否拥有返回的对象。如果这样做,我们需要放弃所有权...
一个反例(考虑自动释放对象的问题)是当我们考虑与诸如stringWithFormat:之类的方法相关的性能问题时。由于我们通常(1)无法直接控制这些对象的生存期,因此它们可以保留相对较长的时间,并且不必要地增加了应用程序的内存占用。尽管在台式机上这可能影响不大,但在更受限的平台上,这可能是一个重要问题。因此,被认为是在所有平台上使用alloc / init模式的最佳实践,在更受限制的平台上,如果可能的话,强烈建议我们不要使用任何会导致对象自动释放的方法。
(1)我们可以使用自己的本地自动释放池来控制。有关更多信息,请参阅Apple的《内存管理编程指南》。
需要注意的是,如果我们使用C样式的数组来存储对象并且决定使用垃圾回收,则需要使用NSAllocateCollectable(sizeof(id)* size,NSScannedOption)分配该内存并标记该变量作为" __strong"。
通过这种方式,收集器知道它拥有对象,并将在该变量的生存期内将存储在该对象中的对象视为根。
For instance, is it completely illegal to use a pointer to an Objective C object and treat it as an array?
如果不是数组,则为是。
Are you forced to use NSArray and NSMutableArray for data structures?
不。我们可以使用C数组,并且应该可以使用C ++ STL向量(尽管我不使用C ++,所以我不知道具体方法)。
但是没有理由不使用NS {,Mutable} Array
。不要害怕可可框架,因为它们是朋友。
并且不要忘记其他集合类型,例如" NS {,Mutable} Set"和" NS {,Mutable} Dictionary"。