2011-03-28 6 views
0

먼저 할당/초기화 한 다음 복사 한 개체를 해제하는 것과 혼동을 겪습니다. 늘어나는만큼 내가 메모리 관리 매뉴얼을 이해하기 때문에 내가 그것을 할당하고 나중에 그것을 복사하여 2의 가치를 유지해야하기 때문에 내가 객체를 두 번 릴리스해야합니까? 그래서 첫 번째 릴리스에서는 1로, 2에서 0으로 낮 춥니 다. 두 번 해제하면 메시지가 dealloc 객체에 전송됩니다. 한 번 해보면 응용 프로그램에는 문제가 없지만 Objetive C mem을 이해하는 데는 문제가 없습니다. 관리 :)))두 번 풀어 주시겠습니까?

내가 생각할 수있는 유일한 설명은 비 일관적인 컨텍스트에서 개체를 릴리스 할 때 보유 카운트의 값에 관계없이 즉시 해제 할 것입니다. 전체 방법 코드 :

+(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]; 

} 사전에

감사합니다, 루카

스 니펫 우는 소리 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! 


} 

UPDATE입니다

답변

2

규칙을해야하는 것은 아주 간단합니다 : 당신이 소유권을 포기하려는 경우 각 alloc/init, copy 또는 retain 정확히 하나 release 또는 autorelease를 호출해야합니다. alloc/init 중 하나만 호출 했으므로 release 번만 호출 할 수 있습니다.

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

그 이유는 다음과 같습니다 :

이 줄 :로

[tempReturnedElements addObject:[xmlElement copy]]; 

는 작성해야 copy 당신에게 새로운 객체를 제공합니다. xmlElement이 가리키는 개체의 보유 개수/소유권은 변경되지 않지만 새 개체는 이제 사용자의 소유입니다. 당신은 지금 그것을 풀어 놓을 책임이 있습니다. 이 대답의 첫 번째 단락을 참조하십시오. 복사를 호출하면 결과 객체에서 release를 호출해야합니다.

+0

좋아, 나는 복사가 원래 개체의 보유 개수를 변경하지 않는다는 것을 몰랐다. 나는 그것을 읽는 것을 의미한다 그러나 이것을 잊었다. 이것에 감사드립니다 .... 괜찮은 경우 ... 복사는 xmlElement의 복제본을 생성하고 두 객체의 보유는 1입니다. 복사 된 객체가 KennyTM의 응답과 같이 다른 객체에 할당되지 않았으므로 [xmlElement release]를 호출 할 수 없습니다 두 xmlElement (할당 또는 복사) 내가 풀어가는거야 알지 못하기 때문에 두 번? 그래서 autorelease를 사용하고 있습니까? – luigi7up

+0

거의 틀림 :'xmlElement' 변수는 여전히 원래의 객체를 가리키고 있습니다. 그래서 시스템은 당신이 말하는 객체를 "알고"있으며, 보유 수는 1이라고 정확하게 말했기 때문에 하나의'release' 필요합니다.그리고 이제 우리는 복사본을 처리 할 필요가 있습니다 : 당신은 @KennyTM가 제안한 것과 같은 변수로 복사본에 대한 포인터를 잡을 수 있고 나중에 그 변수에'release'를 호출하거나 복사본에서'autorelease'를 직접 호출 할 수 있습니다 (반환 값은 호출 된 객체). 'autorelease'를 사용하면 기본적으로 다음과 같이 말할 수 있습니다 : * 풀 오토 릴리즈 풀, 당신은 지금 주인입니다, 나중에 kthxbye를 풀어주세요. * – DarkDust

+0

설명해 주셔서 고맙습니다 :) 약간의 질문이있었습니다 ... 1. 사전 구현이 유지되면 추가 된 모든 것을 유지하면 왜 원본을 복사하지 않고 복사 한 요소 만 보내야합니까? 사전 릴리스가 유지 될 때까지 원래 객체를 삭제하면 안됩니까? 지금까지 addObject : [object copy]라는 기술을 사용하여 봤던 사전을 사용하는 모든 코드. addObject : 객체가 충분하지 않아야합니까? 2. addObject 메서드를 호출 한 후 또는 현재 컨텍스트의 끝에서 즉시 개체가 사전에 삽입됩니까? Thnx – luigi7up

4

[xmlElement copy]에서 반환 된 객체 (i .이자형. 사본)을 공개해야합니다. 수신자 (xmlElement)의 소유권 (보유 수)은 변경되지 않습니다.

그래서 올바른 방법이

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