2013-05-15 2 views
1

В настоящее время в моем приложении есть производитель, который выводит массив данных; вывод от этого производителя привязан (используя «Bindings» в XIB-файле) к представлению таблицы в моем окне. Производитель выплевывает данные, и он появляется в окне, все хорошо.Ошибка Malloc в Objective C

За исключением того, что мне нужно изменить отображаемые данные. Производитель - стороннее приложение, поэтому я не могу его напрямую изменить, поэтому мне нужно создать объект фильтра, который находится между ними.

Объект Я создал выглядит следующим образом:

@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

Смежные вопросы