Правильно управлять памятью, чтобы предотвратить освобождение объекта CFString (immutable) (зомби)

У меня возникла ситуация, когда я скопировал строку в экземпляр вспомогательного класса, сохранил ее и позже выпустил во время dealloc экземпляра контроллера представления, который выделил бы вспомогательный класс. Это приводит к страшному EXC_BAD_ACCESS. Затем я пошел в Инструменты для отладки зомби. Это дало мне следующую ошибку:

Сообщение Objective C было отправлено освобожденному объекту 'CFString (immutable)' (зомби) по адресу: бла-бла

Когда я затем просматриваю сводную информацию о распределении внутри Инструментов и работаю в обратном направлении после обнаружения зомби, мой первый код появляется впервые при освобождении экземпляра вспомогательного класса. Вот как выглядит вспомогательный класс. Сначала файл.h:

@interface channelButtonTitles : NSObject {
    NSString *channelTitle;
    ...
}

@property (nonatomic,copy)  NSString *channelTitle;
...
@end

Затем файл.m:

@implementation channelButtonTitles
@synthesize channelTitle;
...

- (void)dealloc {
    [channelTitle release];
    ...
}
@end

Теперь соответствующий код из контроллера представления, который использует вспомогательный класс, выглядит следующим образом. В файле.h у меня есть массив, который будет содержать несколько объектов вспомогательного класса следующим образом:

@interface MyVC : UIViewController {
    NSMutableArray *channelTitles;
    ...
}
@property (retain, nonatomic)   NSMutableArray *channelTitles;

Затем в коде.m, я синтезирую channelTitles, у меня тоже есть dealloc метод следующим образом:

- (void)dealloc {
    [channelTitles release];
    ...
}

Наконец, я размещаю экземпляры объектов вспомогательного класса и сохраняю их в channelTitles со строками, хранящимися в channelTitle элементы channelButtonTitles следующее:

[channelTitles removeAllObjects];
self.channelTitles = nil;
channelTitles = [[NSMutableArray alloc] init];
...

for (int i=0; i<numberOfTitles; i++) {
    // For each mediaItem, get the title and subtitle info
    channelButtonTitles *aChannelButtonTitle = [[channelButtonTitles alloc] init];  // create an object to hold the title and miscellaneous data
    aChannelButtonTitle.channelTitle = @"some title";

    [channelTitles addObject: aChannelButtonTitle]; // add the title
    [aChannelButtonTitle release];

}

Таким образом, это техника, которую я использовал много раз прежде, но, кажется, сейчас не в восторге. Когда контроллер представления отключен, и я возвращаюсь к корневому контроллеру представления, dealloc метод на мой взгляд контроллер называется. Что выпускает channelTitles что приводит к вызову dealloc на channelButtonTitles вспомогательные объекты класса, которые хранятся в channelTitles,

Поскольку я использовал copy в свойстве вспомогательного класса, я предполагаю, что владею этой строкой. Следовательно, я выпускаю это. Если я закомментирую [channelTitle release] линия от моего deallocEXC_BAD_ACCESS исчезает, но я подозреваю, что у меня утечка памяти. Пожалуйста, помогите мне понять, что я делаю неправильно.

0 ответов

Другие вопросы по тегам