我是内存管理代码的新手,但我很清楚这个想法。
在通过 XCode 中的泄漏工具使用我的应用程序时,我注意到我只需要清理我的自定义对象,而不是例如动态创建的数组,所以我认为这些数据类型是自动释放的 - 这是有道理的,因为我只需要释放我用作属性的数组,这些数组上有(保留)。
然后我注意到一些奇怪的事情:我在某个像这样初始化的数组上发生泄漏:
NSMutableArray *removals = [NSMutableArray new];
但不是类似的
NSMutableArray *removals = [NSMutableArray arrayWithCapacity:9];
现在,一个设置为"new"的原因是它可以包含 0-99 个项目,而另一个我知道的将始终为 9。因为两个数组稍后都传递给相同的方法基于用户交互,如果我没有在方法结束时释放,我要么得到一个泄漏,要么如果我释放了一个异常!
我把第一个数组改成了
NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];
而且我没有泄漏,也不必发布任何内容。谁能解释一下?
最佳答案
如 memory management rules 中所述, 每当你有一个你用 +alloc
, +new
, -copy
, 或者 -mutableCopy
创建的对象>,您拥有它并负责在某个时候发布它。 (事实上,+new
只是 [[MyClass alloc] init]
的简写。)正如您所指出的,通过 [NSArray new]
创建一个数组而不释放它是内存泄漏。但是,如果您正确处理这个对象,通常可以在某个时候释放它。例如:
如果使用数组的方法是从在创建数组的方法中调用的,那么您应该能够在数组完成后释放它被使用过。如果内部方法需要保留对周围数组的更永久引用,则该方法负责发送
-retain
并最终发送-release
到对象。例如:- (void)myMethod { NSArray *removals = [NSArray new]; // ... [someObject someOtherMethod:removals]; [removals release]; }
如果您在对象的
-init
方法 中创建数组,则-dealloc
方法 可以在对象销毁时释放它。如果您需要创建数组然后从方法中返回它,您就发现了发明自动释放的原因。您的方法的调用者不负责释放对象,因为它不是
+alloc
、+new
、-copy
,或-mutableCopy
方法,但您需要确保它最终被释放。在这种情况下,您在返回对象之前手动调用对象上的-autorelease
。例如:- (NSArray *)myMethod { NSArray *removals = [NSArray new]; // ... return [removals autorelease]; }
当您通过+arrayWithCapacity:
创建数组时,您并没有调用任何一种“特殊”方法,因此您不必释放结果。这可能是用 -autorelease
实现的,很像上面最后一个例子,但不一定。 (顺便说一句,你也可以用 [NSMutableArray array]
创建一个空的自动释放的 NSMutableArray;该方法在 NSArray 中找到,所以它不会出现在 NSMutableArray 下的文档中,但它会创建一个可变的array 当发送到 NSMutableArray 类时。)如果你打算从你的方法中返回数组,你可以使用它作为 [[[NSMutableArray alloc] init] autorelease]
的简写 - 但它只是一条捷径。但是,在许多情况下,您可以使用 -init
或 +new
创建一个对象,并在适当的时候手动释放它。
关于iphone - Objective C 发布、自动发布和数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1219575/