【问题标题】:Memory leak problem and i need help #1内存泄漏问题,我需要帮助 #1
【发布时间】:2011-08-07 11:26:50
【问题描述】:

我对此很陌生,并且似乎在这段代码中有一个我无法修复的泄漏:

仪器以 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];
}

【问题讨论】:

  • 仪器显示什么?有什么具体点吗?
  • 显然您将 managedObjectContext 定义为标题中的属性。属性是如何定义的?
  • 仪器显示 NSMutableArray *read_Question = [[NSMutableArray alloc] initWithCapacity: 0];
  • 这样:NSManagedObjectContext *managedObjectContext;
  • 我的意思是:它是用retain定义的吗,属性是什么?

标签: iphone cocoa-touch memory-leaks


【解决方案1】:

这表明您只在 if 语句中返回对象。这意味着如果 if 语句为假,您将不会自动释放数组。或者,也许您没有粘贴整个方法。让我知道。乐器有时很棘手。

【讨论】:

    【解决方案2】:

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

    当我发布时遇到了麻烦, 当然。我确实尝试过改变 三个上的名字并发布 有独特的名字,但确实如此 不工作。

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

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

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

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

    【讨论】:

    • 对不起,我的错误
    • 别担心——我理解你的沮丧。我们都去过那里。关键是退后一步,了解系统和问题,而不仅仅是解决症状。祝你好运。
    • 我现在完全迷失了,尝试了各种方法,但泄漏仍然会弹出:-(
    • 你如何处理该方法返回的数组?贴出代码。
    【解决方案3】:

    仪器告诉你泄漏的对象是被分配的,而不是它必然泄漏的地方。

    虽然您可能不会在所有情况下在从该方法返回时自动释放数组,但您也可能将其保留在其他地方,而不是在保留与释放之间取得平衡。

    【讨论】:

      【解决方案4】:

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

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

      然后重新添加您的版本。

      【讨论】:

      • 虽然这是一个很好的建议,但它可能与泄漏无关。
      【解决方案5】:

      由于我相信来自 picciano 的代码将解决 openingsposter 的问题,这里简单解释一下为什么它应该解决这个问题。

      如果你给一个属性 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];
      

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

      // 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];
      

      这样您就可以确定保留确实发生了。

      我认为访问器设置器的第二种表示法更好,我认为尽可能使用它来设置属性是一个好习惯。在以下网站上阅读更多关于持这种观点的人及其推理的信息:

      【讨论】:

      • 没有一个回答原始问题......他正在泄漏一个数组,而不是一个托管对象上下文。
      • 为什么你认为它是一个数组?
      猜你喜欢
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 2011-03-27
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多