第二次查看tableview后内存泄漏

时间:2011-04-13 14:25:10

标签: iphone objective-c core-data memory-leaks

我有两个UITableViewControllers。我正在推动第二个并在viewDidLoad中调用以下方法。

第二次处理此视图并返回第一个视图时,我发现内存泄漏。

仪器说明问题出现在以下方法的最后一行。

- (void)fetchRecords {   

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:@"Articulation" inManagedObjectContext:[self managedObjectContext]]];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"articulationGroup == %@", selectedArticulationGroup];
    [request setPredicate:predicate];

    static NSArray *sortDescriptors = nil;
    if (!sortDescriptors)
        sortDescriptors = [[NSArray alloc] initWithObject:[[[NSSortDescriptor alloc] initWithKey:@"text" ascending:NO] autorelease]];
    [request setSortDescriptors:sortDescriptors];

    NSError *error = nil;
    NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error];
    if (!fetchResults)
        NSLog(@"no fetch results ArticulationsViewController, error %@", error);
    [request release];

    self.articulationsArray = [NSMutableArray arrayWithArray:fetchResults];

}

我不知道......上床睡觉:'(

5 个答案:

答案 0 :(得分:1)

首先,如果您使用分配分支,则会泄漏sortDescriptors数组。 <肥皂盒>我强烈建议你在所有if / else块周围使用花括号,即使它们只有一行 - 这些错误在事实之后很难找到< / soapbox>

请发布您的dealloc方法和ivar声明。

答案 1 :(得分:0)

好吧,我注意到两件事情可能是正确的,但无论如何我想问一下。

首先,你在if语句中询问:if (!fetchResults)。这意味着fetchResults可能不存在。尽管如此,您仍尝试使用该数组初始化数组。

其次,我不知道你如何分配articulationsArray,但是将行改为self.articulationsArray = [[NSMutableArray alloc] initWithArray:fetchResults]]会有什么影响吗?

答案 2 :(得分:0)

为什么您的sortDescriptors数组是静态的?通常,您会这样做:

NSSortDescriptor *textSort = [[NSSortDescriptor alloc] initWithKey:@"text" ascending:NO];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:textSort]];

[textSort release];

此外,在if (!fetchResults)之后你不应该保存你的数组,但是做这样的事情:

if (!fetchResults)
{
    NSLog(@"no fetch results ArticulationsViewController, error %@", error);
}
else
{
    NSMutableArray *articulationsArray_tmp = [fetchResults mutableCopy];
    self.articulationsArray = articulationsArray_tmp;
    [articulationsArray_tmp release];
}

[request release];

另请注意如何以不同方式设置articulationsArray。人们应该始终小心这些NSMutableArray s ...:)

答案 3 :(得分:0)

这个块完全没必要,而且很危险:

static NSArray *sortDescriptors = nil;
if (!sortDescriptors)
    sortDescriptors = [[NSArray alloc] initWithObject:[[[NSSortDescriptor alloc] initWithKey:@"text" ascending:NO] autorelease]];
[request setSortDescriptors:sortDescriptors];

任何静态对象对内存都有危险,只有在特殊情况下才能使用它们。为什么只将一个本地范围的数组固定到特定的地址/块?所有这些都可以用一行代替:

[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortWithKey:@"text" ascending:NO]]];

......完成了。

此行可能是不必要的,可能会在以后引起问题:

self.articulationsArray = [NSMutableArray arrayWithArray:fetchResults];

为什么需要一个可变的获取对象数组?您无法直接在阵列中添加或删除任何内容,同时保持图表的完整性而无需重新获取。

只需:

self.articulationsArray = fetchResults;

在大多数情况下都能正常工作。

您创建的对象越多,创建泄漏的可能性就越大。让事情尽可能简单。

答案 4 :(得分:0)

嗯......我觉得自己像个鹅。

当我弹回第一个tableViewController时,我没有发布articulationsArray。

我正在使用

- (void)viewDidUnload {
    [self.articulationsArray release];
}

当我应该使用时:

-(void)viewDidDisappear:(BOOL)animated {
    [self.articulationsArray release];
}

ViewDidUnload,从未被调用过。

感谢大家的帮助。