无法释放数组对象,但它们会导致泄漏

时间:2010-07-19 12:26:58

标签: iphone objective-c memory-management memory-leaks instruments

我有2个数组,1在viewDidLoad方法中,1在add方法中(将对象添加到收藏夹)

NSUserDefaults *myDefault = [NSUserDefaults standardUserDefaults];
    NSArray *prefs = [myDefault arrayForKey:@"addedPrefs"]; 
    userAdded = [[NSMutableArray alloc] initWithArray:prefs];

仪器显示这些prefs NSArrays的泄漏。 (上面只显示了一个,ViewDidLoad中的其他内容完全相同)当我尝试释放它们时,应用程序崩溃并且它们是在本地定义的,因此我无法在dealloc方法中释放它们。

是否可以将userAdded NSMutable数组直接分配给arrayForKey?或者会导致不匹配?

如何阻止这种泄漏?

3 个答案:

答案 0 :(得分:0)

文档未指定initWithArray:是否在添加到新数组(userAdded)时将旧数组(prefs)中的对象发送到另一个保留。它应该,因为项目正被添加到新数组。也许当旧数组(prefs)被释放时,userAdded中元素的保留计数下降得太低,对象也被解除分配,应用程序崩溃。为了检查这一点,我在调用initWithArray之前和之后询问了第一个数组的内容是否有保留计数:。

NSUserDefaults *myDefault = [NSUserDefaults standardUserDefaults];
NSArray *prefs = [myDefault arrayForKey:@"addedPrefs"]; 
NSUInteger i, count = [prefs count];
for (i = 0; i < count; i++) {
    NSObject * obj = [prefs objectAtIndex:i];
    NSLog(@"Object: %@, Retain count: %d.", obj, [obj retainCount]);
}
userAdded = [[NSMutableArray alloc] initWithArray:prefs];
for (i = 0; i < count; i++) {
    NSObject * obj = [prefs objectAtIndex:i];
    NSLog(@"Object: %@, Retain count: %d.", obj, [obj retainCount]);
}

对象报告增加的保留计数,因此可以释放prefs数组而不会影响新数组。但运行此代码仍会泄漏NSArray。

所以问题必须在于prefs数组。由于NSUserDelfaults方法arrayForKey:生成prefs数组,但在此方法的名称中找不到单词“alloc”,“new”或“copy”,因此调用方法不拥有prefs数组。最有可能的是,prefs数组被添加到自动释放池中。为了测试这个想法,我通过调用NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];[pool drain]包围了上面的测试代码。运行此代码不会泄漏数组。

所以我认为prefs数组正被添加到一个不会耗尽的自动释放池中。消除此泄漏的最简单方法是在创建prefs数组之前创建自动释放池,并在使用prefs数组完成时耗尽该池。

答案 1 :(得分:0)

-dealloc中发布userAdded。

答案 2 :(得分:-2)

泄密是指alloc没有release。每个alloc(或copy)后面应该跟releaseautorelease某个地方(但不会太快 - 这可能会导致您的崩溃?)

如果您需要保留超出功能范围的userAdded,请将其设为保留属性并分配给self.userAdded

所以做到这一点

self.userAdded = [[[NSMutableArray alloc] initWithArray:prefs] autorelease];

并有一个

@property (nonatomic,retain) NSMutableArray * userAdded;

@synthesize userAdded;

堵塞泄漏。