Лучшее управление памятью IOS @ Вызов функции с возвратом выделенного объекта - PullRequest
2 голосов
/ 02 сентября 2011

У меня есть функция с типом возвращаемого значения (NSArray / NSData / NSString / NSDictionary и т. Д.). я могу вернуться и использовать, но моя проблема возникает @ освободить объект. Подскажите, пожалуйста, какой из них является лучшим способом управления памятью для возвращаемого объекта. Если что-то не так, пожалуйста, проигнорируйте и предложите свое лучшее решение

Я уже упоминал руководство по управлению памятью Apple

A)

-(NSData *)somefunction2
{  
   NSData *data=[[[NSData alloc]init]autorelease];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{    
NSData *data=[self somefunction2];    
// use data    
}

но большинство блогов советуют избегать автоматического выпуска, поэтому я использовал следующий тип

В)

-(NSData *)somefunction2
{  
   NSData *data=[[NSData alloc]init];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{

NSData *data=[[self somefunction2] retain];

// use data

[data release];

}

С)

-(NSData *)somefunction2
{  
   NSData *data=[[[NSData alloc]init]autorelease];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{

NSData *data=[[self somefunction2] retain];

// use data

[data release];

}

Edit: Еще кое-что. если я попытаюсь передать тот же выделенный объект в некоторый вызов функции Argument или пользовательский объект Delegate, где мне нужно освободить ?? Будь ниже вызова функции или получить сохранить в функции def и затем отпустить.

NSData *data=[[NSData alloc]init];

[self somfunctioncall:data];

или

NSData *data=[[NSData alloc]init];

[delegate mydelegatefunction:data];


-(void)somfunctioncall:(NSdata *)data
{
NSData *newdata =[data retain];
//data use
[data release];}

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

Ответы [ 6 ]

3 голосов
/ 02 сентября 2011

Лучше всего, если метод содержит alloc, init, new or retain, метод возвращает объект retained, а если нет, возвращает объект autoreleased. Я бы предложил это:

-(NSString *)newData
{  
   NSData *data=[[NSData alloc]init];  
    // fill stuff for nsdata
   return data;
}

Так что позже вы можете просто сделать это:

-(void)somefunction
{

NSData *data=[self newData];

// use data

[data release];

}
2 голосов
/ 02 сентября 2011

Управление памятью iOS иногда может сбивать с толку!Во-первых, я предлагаю вам всегда запускать анализатор в XCode, который будет указывать на возможные утечки памяти, это может быть чрезвычайно полезно!

Поскольку данные являются локальной переменной, я считаю, что по умолчанию это авто-релиз в обеих функциях.

Я вижу, что Оскар только что дал вам улучшенный код, за который я бы тоже проголосовал.

1 голос
/ 03 сентября 2011

A в порядке. Вы возвращаете создать объект и возвращаете автоматически выпущенный объект. Другая функция использует этот объект, и, поскольку ему не нужно удерживать его после метода, ему не нужно сохранять или освобождать его.

Нет ошибки с использованием автоматического выпуска в правильном месте. Методы, которые не имеют новых, alloc в имени возвращают автоматически освобожденные объекты, поэтому можно возвращать автоматически освобожденный объект в getData (который имеет неправильное имя, но давайте пока оставим это).

авто-релиз не рекомендуется в других местах, потому что он увеличивает верхний предел памяти. И он используется неправильно, когда используется лениво - программистами, которые не уверены, когда безопасно выпускать на принадлежащем объекте, поэтому вместо этого они просто автоматически выпускают их.

1 голос
/ 02 сентября 2011

Я лично предпочитаю третий (С) способ. Но нет необходимости сохранять и выпускать data в someFunction.

0 голосов
/ 03 сентября 2011

Не избегайте autorelease.

Если блог говорит вам избегать autorelease, они дают вам плохой совет. Это преждевременная оптимизация производительности. Использование autorelease приводит к упрощению кода и почти никогда не снижает производительность. И несколько раз ухудшает производительность , это легко исправить.

«А» является правильным.

«B» является неправильным, поскольку не соответствует соглашениям об именах Objective-C. Это важно Много. Когда вы изучите соглашения Objective C, вам будет трудно интегрировать этот код. Компилятор, вероятно, выдаст вам плохие предупреждения. И следующая версия llvm будет иметь автоматический подсчет ссылок, что означает, что вы можете положиться на компилятор для написания кода управления памятью для ваших объектов Objective-C. Он делает это на основе соглашений, поэтому он потерпит неудачу.

«С» также является правильным, но в этом случае неоправданно сложным. Если при работе с данными существует вероятность истощения пула автоматического выпуска, это будет правильный код.

0 голосов
/ 03 сентября 2011

«А» правильно. Совет, чтобы избегать autorelease в iOS, - это повышение производительности при управлении временем жизни объекта в пределах одного метода, не между методами.

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