当前位置:  开发笔记 > IOS > 正文

Objective-C:修复方法中的内存管理

如何解决《Objective-C:修复方法中的内存管理》经验,为你挑选了1个好方法。

我几乎在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.那是因为数组和字典超出了这种方法的范围.在arraydictionary类方法创建的自动释放实例NSArrayNSMutableDictionary对象.如果调用者没有明确地保留它们,它们将在应用程序事件循环的下一轮中自动释放.

我还删除了永远不会被执行的代码.该CXMLNode name方法表示它返回一个字符串,因此测试将始终为true.

如果mutableDictnil,你有更大的问题.它抛出异常比静默失败更好,所以我也放弃了那个测试.

我还使用了相对较新的for枚举语法,它消除了你的计数器变量.

我将一些变量和方法重命名为Cocoa-ish.Cocoa与大多数语言的不同之处在于,使用像"create"这样的动词通常被认为是不正确的,除非你特别想让调用者负责释放你返回的任何对象.

你没有做任何事情theError.您应该检查并报告错误,否则nil如果您不打算检查则传入.使应用程序构建一个你不会使用的错误对象是没有意义的.

我希望这有助于你指出正确的方向.



1> Alex..:

这是您的代码的等效重写:

- (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.那是因为数组和字典超出了这种方法的范围.在arraydictionary类方法创建的自动释放实例NSArrayNSMutableDictionary对象.如果调用者没有明确地保留它们,它们将在应用程序事件循环的下一轮中自动释放.

我还删除了永远不会被执行的代码.该CXMLNode name方法表示它返回一个字符串,因此测试将始终为true.

如果mutableDictnil,你有更大的问题.它抛出异常比静默失败更好,所以我也放弃了那个测试.

我还使用了相对较新的for枚举语法,它消除了你的计数器变量.

我将一些变量和方法重命名为Cocoa-ish.Cocoa与大多数语言的不同之处在于,使用像"create"这样的动词通常被认为是不正确的,除非你特别想让调用者负责释放你返回的任何对象.

你没有做任何事情theError.您应该检查并报告错误,否则nil如果您不打算检查则传入.使应用程序构建一个你不会使用的错误对象是没有意义的.

我希望这有助于你指出正确的方向.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有