【问题标题】:Malloc error in Objective CObjective C 中的 Malloc 错误
【发布时间】:2013-05-15 19:51:33
【问题描述】:

现在在我的应用程序中有一个输出数据数组的生产者;该生产者的输出被绑定(使用 XIB 文件中的“绑定”)到我窗口中的表视图。生产者吐出数据,显示在窗口中,一切正常。

除了我需要修改显示的数据。生产者是第三方应用,所以无法直接修改,所以需要创建一个介于两者之间的过滤器对象。

我创建的对象如下所示:

@interface testFilter: NSObject {
id output;
}
-(void)setInput:(id)s;
@end

我更改了绑定,以便生产者的输出进入我的输入:

[myFilter bind:@"input" toObject:producer withKeyPath:@"output" options:0];

我的实现如下所示:

-(id)init
{
    self = [super init];
    output = nil;
    return self;
}

- (void)setInput:(id)newInput
{
    int nEntries = (int)[newInput count];
    id copiedArray = [NSMutableArray arrayWithCapacity:3];
    for (id entry in newInput)
    {
        id copiedEntry = [entry mutableCopy];
        // blah blah make some changes to copiedEntry
        [copiedArray addObject:copiedEntry];
        [copiedEntry release];   // I'm done with it, copiedArray added his own retain
    }
    [self setValue:copiedArray forKey:@"output"];

    [copiedArray release];   // I'm done with it, setValue/output added a retain
}

但这会因错误而崩溃:

“malloc: *** 对象 0x108e00870 的错误:被释放的指针未被分配”

...直到我删除 [copiedArray release] 行。

我认为我应该发送[copiedArray release] 有错吗?

我还能检查什么/推荐的调试此类问题的方法是什么?

【问题讨论】:

  • 推荐的方式是使用 ARC 并且从不显式调用 release。
  • 顺便说一下,[newInput valueForKey:@"mutableCopy"] 将做与大多数for 循环相同的事情,即创建一个数组(假设newInput 是一个数组,因为你没有声明它的类型) 的输入对象的可变副本。您仍然需要一个 for 循环,但该循环只会进行您注释掉的更改。
  • @PeterHosey,-valueForKey: 会补偿-mutableCopy 返回保留对象的事实,还是会泄漏复制的条目?
  • @BrentRoyal-Gordon:好问题。我不知道,但我的猜测是否定的。 (如果没有,你可以用另一个valueForKey: 来破解它,这次得到autorelease。也就是说,使用带有mutableCopy 的KVC 一开始就非常难,而对autorelease 做同样的事情更是如此.)

标签: objective-c cocoa retain


【解决方案1】:
id copiedArray = [NSMutableArray arrayWithCapacity:3];

这将创建一个自动释放的对象。你不应该释放自动释放的对象。

要么删除您的发布调用,要么将该行更改为:

id copiedArray = [[NSMutableArray alloc] initWithCapacity:3];

话虽如此,请考虑使用Automatic Reference Counting (ARC)


来自Advanced Memory Management Programming Guide

您拥有自己创建的任何对象

您使用名称以alloc 开头的方法创建对象, newcopymutableCopy(例如,allocnewObjectmutableCopy)。

您可以使用保留获取对象的所有权

接收到的对象通常保证在 方法,并且该方法也可以安全地返回 对其调用者的对象。您在两种情况下使用retain:(1)在 访问器方法或初始化方法的实现,采取 您想要存储为属性值的对象的所有权; (2) 防止对象因某些副作用而无效 其他操作。

当您不再需要它时,您必须放弃您拥有的对象的所有权

您通过向对象发送release 放弃对对象的所有权 消息或autorelease 消息。在可可术语中, 因此,通常会提到放弃对象的所有权 作为“释放”一个对象。

您不得放弃不属于您的对象的所有权

这只是先前政策规则的推论,声明

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多