2013-05-15 68 views
1

現在在我的應用程序中有一個生產者輸出一組數據;來自該生產者的輸出被綁定(使用XIB文件中的「綁定」)到我的窗口中的表視圖。生產者吐出數據,並在窗口中顯示,一切正常。目標C中的Malloc錯誤

除了我需要修改顯示的數據。生產者是第三方應用程序,所以我不能直接修改它,所以我需要創建一個位於兩者之間的過濾器對象。

我創建的對象看起來是這樣的:

@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: *** error for object 0x108e00870: pointer being freed was not allocated"

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

我錯在認爲我應該發送[copiedArray release]

還有什麼可以檢查/什麼是建議的方式來調試這樣的問題?

+2

推薦的方法是使用ARC,從不顯式調用發佈的。 – mah

+1

順便說一句,'[newInput valueForKey:@「mutableCopy」]'會做與'for'循環的大部分相同的事情,這是爲了創建一個數組(假設'newInput'是一個數組,因爲你沒有聲明它類型)輸入對象的可變副本。你仍然需要一個'for'循環,但是這個循環將不會做任何事情,而只是做出你註釋掉的變化。 –

+1

@PeterHosey,將'-valueForKey:'補償'-mutableCopy'返回一個保留對象的事實,還是會泄漏複製的條目? –

回答

9
id copiedArray = [NSMutableArray arrayWithCapacity:3]; 

這將創建一個自動釋放對象。你不應該釋放自動釋放的對象。

要麼刪除您發佈的呼叫,或更改線路是:

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

話雖這麼說,可考慮使用Automatic Reference Counting (ARC)


Advanced Memory Management Programming Guide

You own any object you create

You create an object using a method whose name begins with alloc , new , copy , or mutableCopy (for example, alloc , newObject , or mutableCopy).

You can take ownership of an object using retain

A received object is normally guaranteed to remain valid within the method it was received in, and that method may also safely return the object to its invoker. You use retain in two situations: (1) In the implementation of an accessor method or an init method, to take ownership of an object you want to store as a property value; and (2) To prevent an object from being invalidated as a side-effect of some other operation.

When you no longer need it, you must relinquish ownership of an object you own

You relinquish ownership of an object by sending it a release message or an autorelease message. In Cocoa terminology, relinquishing ownership of an object is therefore typically referred to as 「releasing」 an object.

You must not relinquish ownership of an object you do not own

This is just corollary of the previous policy rules, stated