Правильно управлять памятью, чтобы предотвратить освобождение объекта 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]
линия от моего dealloc
EXC_BAD_ACCESS исчезает, но я подозреваю, что у меня утечка памяти. Пожалуйста, помогите мне понять, что я делаю неправильно.