Выпускать 2 раза? - PullRequest
       6

Выпускать 2 раза?

0 голосов
/ 28 марта 2011

Я запутался с освобождением объекта, который я сначала выделил / инициализировал, а затем скопировал. Насколько я понял руководство по управлению памятью, я должен отпустить объект 2 раза, потому что, выделив его, а затем скопировав, я должен был сохранить значение 2? Итак, первый релиз понизит его до одного, а второй до 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];

}

Заранее спасибо, Luka

Ответы [ 2 ]

4 голосов
/ 28 марта 2011

В [xmlElement copy] только возвращенный объект (т.е. копия) должен быть освобожден. Владение получателя (xmlElement) (сохранение счета) не изменяется.

Так что правильный путь должен быть

    NSDictionary* xmlElemCopy = [xmlElement copy];
    [tempReturnedElements addObject:xmlElemCopy];
    [xmlElemCopy release];
    [xmlElement release];
2 голосов
/ 28 марта 2011

Правило довольно простое: для каждого alloc/init, copy или retain вы должны назвать ровно один release или autorelease, если хотите отказаться от владения.Вы только что позвонили alloc/init, поэтому вы можете звонить release только один раз.

Эта строка:

[tempReturnedElements addObject:[xmlElement copy]];

должна быть записана как:

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

Причина в том, что copy дает вам новый объект.Сохранение количества / владения объектом, на который указывает xmlElement, не изменяется, но новый объект теперь принадлежит вам.Вы ответственны за выпуск этого сейчас.См. Первый абзац в этом ответе: вы вызвали copy, вам нужно вызвать release для результирующего объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...