内存泄漏问题,我需要帮助#1

时间:2011-04-17 21:11:10

标签: iphone cocoa-touch memory-leaks

我是非常新的,似乎在这段代码中有一个我无法解决的漏洞:

仪器在这一行显示100%:

  

NSMutableArray * read_Question = [[NSMutableArray alloc] initWithCapacity:0];

我尝试了各种各样的东西,但却无法修复它。

任何人都可以建议我如何继续?

- (NSMutableArray *)readQuestion: (int)questionNr {

NSMutableArray *read_Question = [[NSMutableArray alloc] initWithCapacity: 0];

NSError *error;
//=========PREPARE CORE DATA DB===========//
if (managedObjectContext == nil) {
    managedObjectContext = [(FamQuiz_R0_1AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; }
    // Define qContext
    NSManagedObjectContext *qContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"questions" inManagedObjectContext:qContext];
    [fetchRequest setEntity:entity];

    NSArray *fetchedObjects = [qContext executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *info in fetchedObjects) {
        if ([[info valueForKey:@"idQ"] intValue] == questionNr) { 
            [read_Question addObject:[info valueForKey:@"question"]];
            [read_Question addObject:[info valueForKey:@"qRightAnswer"]];
            [read_Question addObject:[info valueForKey:@"qWrongAnswer1"]];
            [read_Question addObject:[info valueForKey:@"qWrongAnswer2"]];
        }
    }   
    [fetchRequest release];
    return [read_Question autorelease];
}

5 个答案:

答案 0 :(得分:1)

它只会在if语句中返回对象。这意味着如果if语句为false,则不会自动释放数组。或许你没有粘贴整个方法。让我知道。仪器有时很棘手。

答案 1 :(得分:1)

这是您的另一个问题的Memory leak problem and i need help #1

  

当我发布时我遇到了麻烦,   当然。我确实试图改变   这三个人的名字就这样发布了   有独特的名字,但确实如此   不行。

更改三个不同文件的名称?这不会做任何事情,它表明你还没有完全围绕对象,指针和内存管理。

Objective-CMemory Management指南会有所帮助。

  

这可能是泄漏的原因   我有这个.m文件吗?

Nope - 正如我在另一个问题中回答的那样,泄漏很可能是因为你保留了该方法返回的对象,然后不在任何地方释放它。

答案 2 :(得分:0)

仪器告诉你泄漏的物体是否被分配,而不是必须泄露的地方。

虽然在从该方​​法返回时,您可能无法在所有情况下自动释放该数组,但您可能还会将其保留在其他位置,而不是通过发布来保留该数据。

答案 3 :(得分:0)

我假设您将属性managedObjectContext设置为“retain”。将行更改为此(包括“self”以便保留):

if (self.managedObjectContext == nil) { self.managedObjectContext = [(FamQuiz_R0_1AppDelegate *)
                                                       [[UIApplication sharedApplication] delegate] managedObjectContext]; }

然后重新添加您的版本。

答案 4 :(得分:0)

因为我相信来自picciano的代码将解决开幕词的问题,这里有一个小小的解释为什么它应该解决这个问题。

如果您为属性提供 retain 属性,它将创建一个看起来像这样(简化)的访问器方法:

@property (nonatomic, retain) NSValue *value;

- (void)setValue:(NSValue *)aValue {
    value = [aValue retain];
}

只有当retainCount达到0时才释放一个对象,使用retain,alloc和copy会增加retainCount。请记住:只有在使用访问器方法时才会实际发生保留(除了使用alloc,保留和直接复制)。当使用以下方法之一时,通常会调用访问器方法:

// the 2 most obvious ways to call the accessor methods ...
object.value = someValue;
[object setValue:someValue];

您在代码中创建了一个retain属性,但是您没有使用访问器方法,因此从未保留该对象。

// no accessor used here ...
managedObjectContext = [(FamQuiz_R0_1AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

如果你要从这一点开始释放它,它会导致崩溃,因为retainCount实际上会在某个时候变为-1(因为它从来没有达到1)。因此,您应该设置如下属性:

// the dot-notation syntax to make use of the accessor method ...
self.managedObjectContext = [(FamQuiz_R0_1AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

或(在我看来最好):

// making use of the accessor method directly, which is very unambiguous ...
NSManagedObjectContext *context = [(FamQuiz_R0_1AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
[self setManagedObjectContext:context];

通过这种方式,您可以确定保留实际发生。

对我来说,访问者设置者的第二个符号是优越的,我认为尽可能使用它来设置属性是个好习惯。阅读更多关于在以下网站上分享此观点及其推理的人的信息: