Я предполагаю, что мое понимание того, как выполнить глубокое копирование, еще не пришло. То же самое с некоторой неоптимальной обработкой памяти, которую я выполняю ниже. Этот код ниже, вероятно, изображает мелкую копию, и я полагаю, что это может быть моей проблемой. У меня есть код печенья для примера, который выглядит следующим образом:
NSArray *user = [[xmlParser createArrayWithDictionaries:dataAsXML
withXPath:kUserXPath] retain];
if([user count] > 0) {
self.name = [[user valueForKey:@"name"] copy];
}
// Crash happens if I leave the next line un-commented.
// But then we have a memory leak.
[user release];
[xmlParser release];
К сожалению, когда я комментирую [user release]
, код работает, но у нас есть очевидная утечка памяти. Метод createArrayWithDictionaries:withXPath:
был переработан вчера вечером, когда SO-сообщество помогло мне лучше понять управление памятью. Вот как это выглядит:
- (NSArray *)createArrayWithDictionaries:(NSString *)xmlDocument
withXPath:(NSString *)XPathStr {
NSError *theError = nil;
NSMutableArray *dictionaries = [NSMutableArray array];
CXMLDocument *theXMLDocument = [CXMLDocument alloc];
theXMLDocument = [theXMLDocument initWithXMLString:xmlDocument
options:0
error:&theError];
NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];
for (CXMLElement *xmlElement in nodes) {
NSArray *attributes = [xmlElement attributes];
NSMutableDictionary *attributeDictionary;
attributeDictionary = [NSMutableDictionary dictionary];
for (CXMLNode *attribute in attributes) {
[attributeDictionary setObject:[attribute stringValue]
forKey:[attribute name]];
}
[dictionaries addObject:attributeDictionary];
}
[theXMLDocument release];
return dictionaries;
}
Я предполагаю, что здесь может возникнуть несколько проблем:
- Произошла автоматическая разблокировка массива словарей, поэтому мое приложение зависало.
- Я не выполняю глубокую копию, только мелкую копию. Таким образом, когда освобождается пользовательский массив,
self.name
делается для.
С NSZombieEnabled
я вижу следующее:
*** -[CFString respondsToSelector:]:
message sent to deallocated instance 0x1ae9a0
Кроме того, последний вызов, когда обратная трассировка показывает, что происходит сбой, содержит следующий код в отдельном модуле от двух других методов:
User *u = self.user;
NSString *uri = [NSString stringWithFormat:@"%@/user/%@/%@",
[self groupName], u.userId, kLocationsUri];
Между всем автоматическим выпуском / копированием / сохранением, происходящим между клиентским кодом и createArrayWithDictionaries:withXPath
, я немного сбит с толку относительно реальной проблемы здесь. Еще раз спасибо за помощь в понимании.