【问题标题】:NSMutableArray destructionNSMutableArray 销毁
【发布时间】:2008-10-07 18:05:04
【问题描述】:

我有一个数组NSMutableArray,里面有快乐的对象。每当我尝试清除所有对象的数组并重新填充它时,这些对象就会恶意打开(泄漏)我。

像这样在init函数中分配

self.list = [NSMutableArray array];

我用来清除它的不同方法包括:

self.list = nil;
self.list = [NSMutableArray array];

和

[self.eventList removeAllObjects];

显式分配和释放数组也不起作用。仅当我尝试重置列表时才会发生泄漏。

我是在重置时错过了一步还是这是另一个问题?

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    您是如何创建泄漏的对象的? 如果你做了这样的事情:

    - (void)addObjectsToArray {
    
        [list addObject:[[MyClass alloc] init];
    
        OtherClass *anotherObject = [[OtherClass alloc] init];
        [list addObject:anotherObject];
    }
    

    那么当列表被释放时你会泄漏两个对象。

    您应该将任何此类代码替换为:

    - (void)addObjectsToArray {
    
        MyClass *myObject = [[MyClass alloc] init];
        [list addObject:myObject];
        [myObject release];
    
        OtherClass *anotherObject = [[OtherClass alloc] init];
        [list addObject:anotherObject];
        [anotherObject release];
    }
    

    更详细的:

    如果您遵循第一个模式,则根据您拥有的Cocoa memory management rules,您创建了两个对象。放弃所有权是您的责任。否则,该对象将永远不会被释放,并且您会看到泄漏。

    但是,您不会立即看到泄漏,因为您将对象传递给数组,该数组也获得了它们的所有权。只有当您从数组中删除对象或数组本身被释放时,才会识别出泄漏。当其中任何一个事件发生时,数组将放弃对象的所有权,它们将在您的应用程序中保持“活动”状态,但您不会对它们有任何引用。

    【讨论】:

      【解决方案2】:

      您是指数组中的对象泄漏吗?

      您如何将对象添加到数组中?阵列将保留它们,因此您需要在将它们添加到阵列后自动释放或释放它们。否则在数组被释放后,对象仍然会被保留(泄露)。

      MyEvent *event = [[MyEvent alloc] initWithEventInfo:info];
      [self.eventList addObject:event];
      [event release];
      
      MyEvent *otherEvent = [[[MyEvent alloc] initWithEventInfo:otherInfo] autorelease];
      [self.eventList addObject:otherEvent];
      

      【讨论】:

      • - (void)addEventToList:(Event *)inEvent { [self.list addObject:inEvent]; [事件发布]; } 传递的对象是这样创建的 [[Event alloc] init];
      • 无论传递什么 inEvent 都应该释放它,而不是传递给它的代码。发布一个你不知道其出处的对象是不好的。
      • 每次我尝试清除阵列时仍然有泄漏。有史以来最奇怪的事情。我有创建事件的方法,在它通过后释放它。一切正常,无需删除数组中的所有对象。
      【解决方案3】:

      您的@property 声明是什么样的?你在合成访问器吗?如果是这样,您需要@property(retain)。我假设当您说这些对象正在攻击您时,您指的是核心转储(EXC\_BAD\_ACCESS)。

      【讨论】:

      • @property (nonatomic, 保留) NSMutableArray *list;我确实有一个综合,但核心转储仅在我尝试手动释放对象时发生。我打开我的意思是对象泄漏(我认为)
      • 你怎么知道他们在泄露?你在检查仪器\泄漏吗?如果您获得了错误的访问权限,这意味着您正在释放已经释放的东西。泄漏更难找到,因为您需要使用工具来捕获它们(或者只是看到您的内存增长)。
      • 所以,如果你正在做 [list addObject:[[MyObj alloc] init];之后 [list removeAllObjects];你可能漏水了。解决方案是提供一个返回自动释放对象的类方法。
      • 我正在使用仪器来监测泄漏。您返回自动释放对象的建议听起来不错。我可以添加 [self autorelease] 吗?到我重写的 init 方法的 return 语句来解决这个问题?
      • 它不应该在 init 方法中,因为它违反了初始化合同。推荐的习惯用法类似于:[MyObject object] 或 [MyObject objectWithProperty:...} 这样做:MyObject (obj = [[MyObject alloc] init] return [obj autorelease];
      【解决方案4】:

      如果仅在您尝试重置列表时发生泄漏,那么您有其他人/其他人正在使用您刚刚尝试释放的其他对象。

      【讨论】:

        【解决方案5】:

        我想说我这里没有足够的信息来给你一个很好的答案。你是说NSMutableArray 仍然被分配,但是是空的并且里面没有任何对象,但是之前在数组中的对象仍然被分配,即使它们应该在应用程序中被释放?

        如果是这种情况,数组可能是空的,但是您的对象没有处理发送给它们的 dealloc 消息,在这种情况下,对象仍然在内存中,但没有被任何东西引用。

        为了帮助你,我想确切地知道 MallocDebug 究竟说什么被泄露了。此外,@Elfred 在检查数组的 @property 方法时给出了一些很好的建议,实际上应该保留或复制。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-17
          • 1970-01-01
          • 1970-01-01
          • 2015-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-06
          相关资源
          最近更新 更多