iphone - 自动释放池和内存管理

原文 标签 iphone memory-management

Autorelease pool and memory management

I'm using the following function to put each "facility" node of my XML in a NSMutable array:

-(void) grabXML {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    CXMLDocument *doc = [[[CXMLDocument alloc] initWithData:data options:0 error:nil] autorelease];

    NSArray *nodes = [[doc rootElement] nodesForXPath:@"//facilities" error:nil];

    for (CXMLNode *itemNode in nodes)
    {               
        for (CXMLNode *eventNode in [itemNode children])
        {           
            if ([[eventNode name] isEqualToString:@"facility"]) {

                [content addObject:[eventNode copy]];               

            }

        }
    }

    loading = FALSE; 
    [table reloadData];

    [pool release];

}

Note that the pool is necessary, 'cause i call the grabXML method in a separate thread.

Using instruments i can see that the following line generates a leak

[content addObject:[eventNode copy]];

And if i change it to

[content addObject:eventNode];

i'm not able to access the XCMLNode later (it seems to be null).

I can avoid the leak putting this on my dealloc method:

for (CXMLNode *node in content) {
    [node release];
}

But i think i'm doing something wrong... or at least i'm not aware of what's going on... Please can you give me a clue?

Thanks!

Answer

copy creates an object with a retain count of 1, -addObject: adds an additional retain, so you have to either release eventNode after adding it to the array or autorelease the copy:

[content addObject:[[eventNode copy] autorelease]];

翻译

我正在使用以下函数将XML的每个“设施”节点放入NSMutable数组中:

-(void) grabXML {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    CXMLDocument *doc = [[[CXMLDocument alloc] initWithData:data options:0 error:nil] autorelease];

    NSArray *nodes = [[doc rootElement] nodesForXPath:@"//facilities" error:nil];

    for (CXMLNode *itemNode in nodes)
    {               
        for (CXMLNode *eventNode in [itemNode children])
        {           
            if ([[eventNode name] isEqualToString:@"facility"]) {

                [content addObject:[eventNode copy]];               

            }

        }
    }

    loading = FALSE; 
    [table reloadData];

    [pool release];

}


请注意,该池是必需的,因为我在单独的线程中调用了grabXML方法。

使用仪器,我可以看到以下行会产生泄漏

[content addObject:[eventNode copy]];


如果我将其更改为

[content addObject:eventNode];


我以后无法访问XCMLNode(它似乎为空)。

我可以避免将其放在我的dealloc方法上的泄漏:

for (CXMLNode *node in content) {
    [node release];
}


但是我认为我做错了...或者至少我不知道发生了什么...请您能给我一个提示吗?

谢谢!
最佳答案
copy创建一个保留计数为1的对象,-addObject:添加一个额外的保留,因此您必须在将eventNode添加到数组后释放它或自动释放该副本:

[content addObject:[[eventNode copy] autorelease]];
相关推荐

iphone - Apple Match-O链接器错误:“ _ Main”,引用自;

iphone - uiwebview(iphone)上的自定义按钮

iphone - 使用UINavigationBarController作为第一个选项卡以编程方式将UITabBarController添加到现有导航控制器

iphone - 在通过MKStoreKit购买的应用中失败:“ iTunes连接产品中的问题配置:xxx”

iphone - 在选项卡栏(如键盘)上设置动画选择器视图

iphone - 由于使用保留属性而导致的内存泄漏

iphone - 由于未捕获的异常'NSGenericException而终止应用程序

iphone - 在iPad上启用UIiStatusBar,在通用iOS应用中为iPhone禁用

iphone - 将视图作为子视图添加到多个视图时遇到麻烦-iPhone开发者

iphone - iPhone对象检查释放