我几乎在Objective-C中理解简单的引用计数/内存管理,但是我在使用下面的代码时遇到了困难.我正在发布mutableDict(在下面的代码中注释),它在我的代码中造成了不利的行为.如果我让内存泄漏,它会按预期工作,但这显然不是这里的答案.;-)你们中任何一个更有经验的人是否都能够指出我正确的方向,因为我可以重新编写任何一种方法来更好地处理我的内存占用?主要是我如何管理NSMutableDictionary*mutableDict,因为这是罪魁祸首.我想了解这个问题,而不仅仅是复制/粘贴代码 - 所以一些评论/反馈是理想的.谢谢大家.
- (NSArray *)createArrayWithDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr { NSError *theError = nil; NSMutableArray *mutableArray = [[[NSMutableArray alloc] init] autorelease]; //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init]; CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError] retain]; NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError]; int i, j, cnt = [nodes count]; for(i=0; i < cnt; i++) { CXMLElement *xmlElement = [nodes objectAtIndex:i]; if(nil != xmlElement) { NSArray *attributes = [NSArray array]; attributes = [xmlElement attributes]; int attrCnt = [attributes count]; NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init]; for(j = 0; j < attrCnt; j++) { if([[[attributes objectAtIndex:j] name] isKindOfClass:[NSString class]]) [mutableDict setValue:[[attributes objectAtIndex:j] stringValue] forKey:[[attributes objectAtIndex:j] name]]; else continue; } if(nil != mutableDict) { [mutableArray addObject:mutableDict]; } [mutableDict release]; // This is causing bad things to happen. } } return (NSArray *)mutableArray; }
Alex.. 5
这是您的代码的等效重写:
- (NSArray *)attributeDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr { NSError *theError = nil; NSMutableArray *dictionaries = [NSMutableArray array]; CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError]; NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError]; for (CXMLElement *xmlElement in nodes) { NSArray *attributes = [xmlElement attributes]; NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary]; for (CXMLNode *attribute in attributes) { [attributeDictionary setObject:[attribute stringValue] forKey:[attribute name]]; } [dictionaries addObject:attributeDictionary]; } [theXMLDocument release]; return attributeDictionaries; }
注意我只引用了引用计数theXMLDocument
.那是因为数组和字典超出了这种方法的范围.在array
和dictionary
类方法创建的自动释放实例NSArray
和NSMutableDictionary
对象.如果调用者没有明确地保留它们,它们将在应用程序事件循环的下一轮中自动释放.
我还删除了永远不会被执行的代码.该CXMLNode
name
方法表示它返回一个字符串,因此测试将始终为true.
如果mutableDict
是nil
,你有更大的问题.它抛出异常比静默失败更好,所以我也放弃了那个测试.
我还使用了相对较新的for
枚举语法,它消除了你的计数器变量.
我将一些变量和方法重命名为Cocoa-ish.Cocoa与大多数语言的不同之处在于,使用像"create"这样的动词通常被认为是不正确的,除非你特别想让调用者负责释放你返回的任何对象.
你没有做任何事情theError
.您应该检查并报告错误,否则nil
如果您不打算检查则传入.使应用程序构建一个你不会使用的错误对象是没有意义的.
我希望这有助于你指出正确的方向.
这是您的代码的等效重写:
- (NSArray *)attributeDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr { NSError *theError = nil; NSMutableArray *dictionaries = [NSMutableArray array]; CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError]; NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError]; for (CXMLElement *xmlElement in nodes) { NSArray *attributes = [xmlElement attributes]; NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary]; for (CXMLNode *attribute in attributes) { [attributeDictionary setObject:[attribute stringValue] forKey:[attribute name]]; } [dictionaries addObject:attributeDictionary]; } [theXMLDocument release]; return attributeDictionaries; }
注意我只引用了引用计数theXMLDocument
.那是因为数组和字典超出了这种方法的范围.在array
和dictionary
类方法创建的自动释放实例NSArray
和NSMutableDictionary
对象.如果调用者没有明确地保留它们,它们将在应用程序事件循环的下一轮中自动释放.
我还删除了永远不会被执行的代码.该CXMLNode
name
方法表示它返回一个字符串,因此测试将始终为true.
如果mutableDict
是nil
,你有更大的问题.它抛出异常比静默失败更好,所以我也放弃了那个测试.
我还使用了相对较新的for
枚举语法,它消除了你的计数器变量.
我将一些变量和方法重命名为Cocoa-ish.Cocoa与大多数语言的不同之处在于,使用像"create"这样的动词通常被认为是不正确的,除非你特别想让调用者负责释放你返回的任何对象.
你没有做任何事情theError
.您应该检查并报告错误,否则nil
如果您不打算检查则传入.使应用程序构建一个你不会使用的错误对象是没有意义的.
我希望这有助于你指出正确的方向.