释放2次?

时间:2011-03-28 08:32:07

标签: iphone release-management

我对释放我首先分配/初始化然后复制的对象感到困惑。据我所知,内存管理手册我应该释放对象2次,因为通过分配它然后再复制它我应该保留2的值? 那么第一次发布会将它降低到1,然后再降低到0? 如果我发布两次,我会将消息发送到dealloc对象。如果我这样做,一旦申请没有问题,但我对Objetive C mem的理解有一个。管理:)))

我能想到的唯一解释是当你从一个特定的上下文中释放一个对象时,它会立即释放它,无论保留计数的值是什么?

在下面的代码片段中,xmlElement令人困惑....

// LSnippet of code for TouchXML
for (CXMLElement *resultElement in resultNodes) {

    NSMutableDictionary *xmlElement = [[NSMutableDictionary alloc] init];

    // Create a counter variable as type "int"
    int counter;

    // Loop through the children of the current  node
    for(counter = 0; counter < [resultElement childCount]; counter++) {

        // Add each field to the blogItem Dictionary with the node name as key and node value as the value
        [xmlElement setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
    }

    // Add the blogItem to the global blogEntries Array so that the view can access it.


    [tempReturnedElements addObject:[xmlElement copy]];
    [xmlElement release];    
    //[xmlElement release]; but NOT!


}

更新:整个方法代码:

+(void) runXPath:(NSString *)xPathExpression{

CXMLDocument *rssParser = [[[CXMLDocument alloc] initWithXMLString:xmlStringContent options:0 error:nil] autorelease];

// Create a new Array object to be used with the looping of the results from the rssParser
NSArray *resultNodes = NULL;


// Set the resultNodes Array to contain an object for every instance of an  node in our RSS feed
resultNodes = [rssParser nodesForXPath:xPathExpression error:nil];

NSMutableArray *tempReturnedElements = [[NSMutableArray alloc]init];

// Loop through the resultNodes to access each items actual data
for (CXMLElement *resultElement in resultNodes) {

    // Create a temporary MutableDictionary to store the items fields in, which will eventually end up in blogEntries
    NSMutableDictionary *xmlElement = [[NSMutableDictionary alloc] init];

    // Create a counter variable as type "int"
    int counter;

    // Loop through the children of the current  node
    for(counter = 0; counter < [resultElement childCount]; counter++) {

        // Add each field to the blogItem Dictionary with the node name as key and node value as the value
        [xmlElement setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
    }

    // Add the blogItem to the global blogEntries Array so that the view can access it.


    [tempReturnedElements addObject:[xmlElement copy]];
//***** Crushes if I use:
//***** [tempReturnedElements addObject:[[xmlElement copy] autorelease]];
    [xmlElement release];



}


[lotojuegosAppDelegate setMyReturnedXmlElements:[tempReturnedElements copy]];

[tempReturnedElements release];

}

提前致谢, 卢卡

2 个答案:

答案 0 :(得分:4)

[xmlElement copy]中,只需要释放返回的对象(即副本)。接收方(xmlElement)的所有权(保留计数)不会更改。

所以正确的方法应该是

    NSDictionary* xmlElemCopy = [xmlElement copy];
    [tempReturnedElements addObject:xmlElemCopy];
    [xmlElemCopy release];
    [xmlElement release];

答案 1 :(得分:2)

规则非常简单:对于每个alloc/initcopyretain,当您想要放弃时,您必须只调用一个releaseautorelease所有权。您只拨打了一个alloc/init,因此您只能拨打release一次。

这一行:

[tempReturnedElements addObject:[xmlElement copy]];

应写成:

[tempReturnedElements addObject:[[xmlElement copy] autorelease]];

原因是:copy为您提供了一个新对象。 xmlElement指向的对象的保留计数/所有权未更改,但新对象现在属于您。你现在负责释放它。请参阅本答案中的第一段:您调用了copy,您需要在生成的对象上调用release。