gpt4 book ai didi

iphone - 为什么我在 Objective C 中进行深拷贝时遇到问题?

转载 作者:行者123 更新时间:2023-12-03 17:18:19 26 4
gpt4 key购买 nike

我假设我对如何执行深层复制的理解还不够。我在下面执行的一些次优内存处理也是如此。下面的代码可能描述了一个浅拷贝,我相信这可能就是我的问题所在。我有一些千篇一律的代码,如下所示:

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];

不幸的是,当我注释掉[用户释放]时,代码可以工作,但我们有明显的内存泄漏。昨晚,当 SO 社区帮助我了解更好的内存管理时,方法 createArrayWithDictionaries:withXPath: 被重构。它看起来像这样:

- (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

Also, the final call where the backtrace shows this is crashing contains the following code in a separate module from the other two methods:

User *u = self.user;
NSString *uri = [NSString stringWithFormat:@"%@/user/%@/%@",
[self groupName], u.userId, kLocationsUri];

在客户端代码和 createArrayWithDictionaries:withXPath 之间发生的所有自动释放/复制/保留之间,我对这里的真正问题有点困惑。再次感谢您帮助我理解。

最佳答案

好的,您不需要保留 createArrayWithDictionaries: 的返回值,因为您没有保留它。返回值是自动释放的。我强烈建议您阅读自动释放的工作原理。您只保留您打算保留在对象中的内容。

此外,user 是一个 NSArray。如果您调用 [user valueForKey:@"name"],您将获得另一个 NSArray 值,表示 name 键的值users 中的每个对象。此外,对象的 name 属性是如何定义的?如果您将其声明为 copyretain(如果您自己不指定,我相信 retain 是默认值),则您不会需要复制或保留该值。事实上,访问者应该始终负责进行内存管理,而不是调用者。如果您编写了自己的访问器(即您没有使用 @synthesize 关键字),则需要确保在那里进行内存管理。

我猜你想写的内容更像是这样的:

    NSArray *user = [xmlParser createArrayWithDictionaries:dataAsXML withXPath:kUserXPath];
if ([user count] > 0)
self.name = [[user objectAtIndex:0] objectForKey:@"name"];

[xmlParser release];

我认为您的问题源于对 Objective-C 内存管理工作原理的误解。

希望这有帮助。

关于iphone - 为什么我在 Objective C 中进行深拷贝时遇到问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/595170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com