Iphone 释放2次?

Iphone 释放2次?,iphone,release-management,Iphone,Release Management,我对释放首先分配/初始化然后复制的对象感到困惑。就我对内存管理手册的理解而言,我应该释放该对象2次,因为通过分配它,然后再复制它,我应该保留值2? 所以第一个版本会把它降到1,第二个版本会降到0? 如果我释放两次,就会将消息发送到dealloc对象。如果我只做一次,在应用中就不会有问题,但在我对Objective C mem的理解中有一个问题。管理层:)) 我能想到的唯一解释是,当您从soecific上下文中释放对象时,无论retain count的值是多少,它都会立即释放它 在代码段中,下面的

我对释放首先分配/初始化然后复制的对象感到困惑。就我对内存管理手册的理解而言,我应该释放该对象2次,因为通过分配它,然后再复制它,我应该保留值2? 所以第一个版本会把它降到1,第二个版本会降到0? 如果我释放两次,就会将消息发送到dealloc对象。如果我只做一次,在应用中就不会有问题,但在我对Objective C mem的理解中有一个问题。管理层:))

我能想到的唯一解释是,当您从soecific上下文中释放对象时,无论retain count的值是多少,它都会立即释放它

在代码段中,下面的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!


}
//TouchXML的代码片段
对于(resultNodes中的CXMLElement*resultElement){
NSMutableDictionary*xmlement=[[NSMutableDictionary alloc]init];
//创建类型为“int”的计数器变量
整数计数器;
//循环遍历当前节点的子节点
用于(计数器=0;计数器<[resultElement childCount];计数器++){
//将每个字段添加到blogItem字典中,节点名称作为键,节点值作为值
[xmlElement setObject:[[resultElement childAtIndex:counter]stringValue]forKey:[[resultElement childAtIndex:counter]名称]];
}
//将blogItem添加到全局blogEntries数组中,以便视图可以访问它。
[tempReturnedElements添加对象:[xmlElement副本]];
[xml元素释放];
//[xmlElement发布];但不是!
}
更新:整个方法代码:

+(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];
+(void)runXPath:(NSString*)xPathExpression{
CXMLDocument*rssParser=[[CXMLDocument alloc]initWithXMLString:xmlStringContent选项:0错误:nil]autorelease];
//创建一个新的数组对象,用于rssParser结果的循环
NSArray*resultNodes=NULL;
//将resultNodes数组设置为包含RSS提要中每个节点实例的对象
resultNodes=[rssParser nodesForXPath:xPathExpression错误:nil];
NSMutableArray*tempReturnedElements=[[NSMutableArray alloc]init];
//循环遍历resultNodes以访问每个项目的实际数据
对于(resultNodes中的CXMLElement*resultElement){
//创建一个临时的MutableDictionary来存储其中的items字段,它最终将在blogEntries中结束
NSMutableDictionary*xmlement=[[NSMutableDictionary alloc]init];
//创建类型为“int”的计数器变量
整数计数器;
//循环遍历当前节点的子节点
用于(计数器=0;计数器<[resultElement childCount];计数器++){
//将每个字段添加到blogItem字典中,节点名称作为键,节点值作为值
[xmlElement setObject:[[resultElement childAtIndex:counter]stringValue]forKey:[[resultElement childAtIndex:counter]名称]];
}
//将blogItem添加到全局blogEntries数组中,以便视图可以访问它。
[tempReturnedElements添加对象:[xmlElement副本]];
//*****如果我使用:
//*****[tempReturnedElements添加对象:[[xmlElement复制]自动删除]];
[xml元素释放];
}
[lotojuegosAppDelegate setMyReturnedXmlElements:[tempReturnedElements copy]];
[临时返回元素释放];
}

提前感谢,,
Luka

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

所以正确的方法应该是

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

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

所以正确的方法应该是

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

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

这一行:

[tempReturnedElements addObject:[xmlElement copy]];
应写为:

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

原因是:
copy
为您提供了一个新对象。
xmlement
指向的对象的保留计数/所有权不变,但新对象现在属于您。你现在负责发布它。请参见答案中的第一段:您调用了copy,您需要对结果对象调用release。

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

这一行:

[tempReturnedElements addObject:[xmlElement copy]];
应写为:

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

原因是:
copy
为您提供了一个新对象。
xmlement
指向的对象的保留计数/所有权不变,但新对象现在属于您。你现在负责发布它。请参阅答案中的第一段:您调用了“复制”,您需要对生成的对象调用“释放”。

好的,我不知道复制不会更改原始对象的保留计数。我是说我读过了,但我忘了这个。谢谢你的这个…。如果我没弄错的话…Copy创建xmlement的副本,两个对象的retain都是1。由于复制的对象没有分配给任何其他对象(如KennyTM的回答中),我不能调用[xmlElement release]两次,因为它不知道我正在释放这两个对象(alloc或复制)中的哪个xmlElement?这就是为什么要使用autorelease?几乎是正确的:
xmlElement
变量仍然指向原始对象,因此系统确实“知道”您正在与哪个对象说话,正如您正确地说的,它的保留计数是1。所以只需要一个
版本
。现在我们需要处理副本:您可以捕获指向c的指针