2011-05-13 122 views
2

我使用下面的函數來把我的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]; 
} 

但我覺得我做錯了什麼......或者至少我不知道發生了什麼事情的...請你能給我一點線索嗎?

謝謝!

回答

6

copy創建爲1的保留計數的對象,-addObject:增加了一個額外保留,所以你必須要麼釋放eventNode將其添加到陣列後或自動釋放的副本:

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

您應該使用

CXMLNode *tempEventNode = [eventNode copy]; 
    [content addObject:tempEventNode]; 
    [tempEvent release]; 

代替,[content addObject:[eventNode copy]];

當您使用[eventNode copy]它使得r etaincount +1,當你直接添加這個副本(如在你的代碼中),你將再次增加+1,因爲數組會保留它。所以對於陣列保留它不是你的責任釋放,但對於你的副本調用你必須釋放它。

[eventNode copy] --> retain count +1 
[content addObject:[eventNode copy]]; -> retaincount +2 

感謝