Вопрос

Похоже, я не понимал управления памятью в объективном C ... вздох.

У меня есть следующий код (обратите внимание, что в моем случае, placemark.thoroughfare а также placemark.subThoroughfare оба заполнены достоверными данными, таким образом if-Донки будут TRUE

item привязан к ManagedObjectContext. Анкет Управляемые переменные в item такие как place иметь сеттеры/getters, созданные с @dynamic. Анкет Таким образом, декларация

@property (nonatomic, retain) NSString *place;
@dynamic place;

Позже в коде, в обратном токодеределегате, я получаю доступ к нему:

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {

if (placemark.thoroughfare) {
    [item.place release];
    item.place = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];        
} else {
    [item.place release];
    item.place = @"Unknown Place";
}
if (placemark.thoroughfare && placemark.subThoroughfare) {
// *** problem is here ***
    [item.place release];
    item.place = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}

Если я не выпущу item.place В помеченном месте в коде инструменты находят утечку памяти. Если я это сделаю, программа вылетает, как только я попытаюсь получить доступ item.place вне метода оскорбления.

Любые идеи?

Это было полезно?

Решение

Прежде всего, я бы так изменил логику:

NSString *newPlace = nil;

if (placemark.thoroughfare && placemark.subThoroughfare) {
    newPlace = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
else {
    if (placemark.thoroughfare) {
        newPlace = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
    }
    else {
        newPlace = @"Unknown Place";
    }
}

item.place = newPlace;    // Either nil of valid string can be assigned to

Использование выпуска для простой повторной инициализации указателя не так рекомендуется многими. Вам не нужно делать это, если это было сохранить память.

Ваша предыдущая логика выпускает дважды. Анкет Какой релиз изначально просто уменьшается retainCount. Анкет Если это 0, то объект находится с решением. Объект не будет осуществляться до тех пор, пока его retainCount является 0.

Предполагая вещь имеет собственность удерживать и с тех пор stringWithFormat: возврат autoreleased Строка, так что во 2 -м выпуске вы пытались выпустить то, что должно было быть autoreleased тем не мение.

Лучший способ очистки объекта несколько раз - просто назначить nil к этому.

Другие советы

Отправной точкой было бы перечитать о свойствах, потому что вам не нужно делать «[item.place Release]». Итак, вы можете удалить их. Динамический код, созданный во время выполнения, чтобы позволить этому свойству автоматически обрабатывает что -либо, что было назначено ранее.

Так же [NSString stringWithFormat:... Создает объект AutorElease (не уверен, что вы знали, что :-) Что означает, что если вы, где вручную управлять памятью для переменной (не свойства), вам придется сохранить/отпустить ее. Но поскольку вы используете свойства, вы этого не делаете.

Я не могу понять, почему инструменты находят утечку памяти. Возможно, какой -то более высокий код связан с этим. Например, если вы пошли item.place = [NSString alloc] initWith...]; Тогда я думаю, что вам это понадобится.

Авария, которую я подозреваю, из -за выпусков, вызывающих удержание количества, чтобы быть нулевым и запускающим ошибки EXEC Bad Access.

Надеюсь, это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top