Каков наилучший способ освободить память в Objective C? - PullRequest
2 голосов
/ 04 февраля 2010

У меня запрос по управлению памятью.

Начнем с примера. Предположим, у нас есть класс следующим образом.

@interface myClass : NSObject {
    NSString *xyz;
}
@end

Теперь посмотрите на реализацию.

@interface myClass : NSObject {
    NSString *xyz;
}
@end

@implementation myClass
-(void)abc{
    // xyz allocted here
}
-(void)pqr{
    // retained or copied many times or may not a single time
}
-(void)mno{
    // retained or copied many times or may not a single time
}
-(void)jpg{
    // may be released more than one time or may be not
}


//-(void)dealloc{
//  [xyz release];
//  [super dealloc];
//}
//
//-(void)dealloc{
//  if(xyz!=nil && [xyz retainCount]>0){ [xyz release]; xyz=nil; }
//  [super dealloc];
//}

-(void)dealloc{
    if(xyz!=nil){ 
        while([xyz retainCount]>0) 
           [xyz release]; 
        xyz=nil; 
    }
    [super dealloc];
}
@end

В приведенном выше коде. У меня есть три функции деллока. Какой из них предпочтительнее? Если ничего из этого, то, пожалуйста, предложите свой.

Я в замешательстве, потому что Цель C говорит, что объект должен быть освобожден каждый раз = каждый раз, когда выделяется / сохраняется

Но большая часть примера кода имеет только одно утверждение "[xyz release];" это не создает утечку памяти?

Ответы [ 5 ]

12 голосов
/ 04 февраля 2010

Это абсолютно неверно:

while([xyz retainCount]>0) 
       [xyz release]; 
    xyz=nil; 

retainCount никогда не вернет 0, потому что как только вы достигнете retainCount 1 и объект будет освобожден, среда выполнения просто освобождает его прямо тогда итам, никогда не уменьшая retainCount .Даже если он уменьшил retainCount, объект теперь освобожден.Как вы собираетесь спросить, что это за retainCount?

В двух словах, ваш дизайн неверен.Если вы не можете следить за тем, как часто вы удерживаете объект более умным способом, тогда у вас будут утечки памяти и, скорее всего, сбой из-за чрезмерного высвобождения объектов (этот цикл while приведет к сбою вашего приложения).

Если вы абсолютно не можете изменить свой код (я бы вам не поверил, если бы вы сказали, что не можете), тогда вы захотите сохранить второй целочисленный ивар, указывающий, сколько раз вы сохранилиxyz, а затем используйте , что , чтобы выяснить, сколько раз вы должны его выпустить.(Тем не менее, это должно быть абсолютным последним шагом, как в Армагеддоне, если это не сработает в течение 30 секунд. Сначала вам действительно нужно провести рефакторинг кода.)

Кроме того, вызабыли вызов [super dealloc] в вашем dealloc методе.

4 голосов
/ 04 февраля 2010
- (void)dealloc {
    [xyz release];
    [super dealloc];
}

... это правильная версия.В Objective-C вы обычно не должны использовать метод retainCount.

Если вы хотите быть очень безопасным, вы также можете написать:

- (void)dealloc {
    [xyz release], xyz = nil;
    [super dealloc];
}
1 голос
/ 04 февраля 2010

объекты, которые сохраняются во время объявления poperty, должны быть освобождены в методе dealloc. Так что, если вы заявляете

@property(nonatomic, retain)NSString xyz;,

вам нужно, чтобы он был выпущен в dealloc как

-(void)dealloc{
    [xyz release];
    [super dealloc]
}

Любая другая выделенная память должна быть освобождена сразу после последнего использования этого объекта из ваших методов.

Так что, если вы выделяете xyz, в

-(void)abc{
    // xyz allocted here
}

тогда вы должны отпустить его в конце того же метода.

-(void)abc{
    // xyz allocted here
// do something with xyz

//release xyz

пример:

        -(void)abc{
           xyz=[[NSString alloc]init];//this may not be what you are following, but i just meant allocating memory
        // do something with xyz


    [xyz release]  

  //release xyz

В этом случае вам не нужно освобождать его в методе dealloc.

Кроме того, если вы свойство, объявляющее xyz и повторяющее его, вы не должны выделять его в своих методах и не должны выпускать

1 голос
/ 04 февраля 2010

Идея состоит в том, что myClass имеет переменную-член (в вашем случае, xyz). Когда объект myClass создается, он должен создать (или получить ссылку на) xyz, добавив только 1 к счету сохранения (зависит от ситуации с помощью сохранения или другими способами).

Не было бы хорошей идеей в каждом методе сохранить xyz с его повторным выпуском. Таким образом, в конце каждого метода локальный объект не должен больше удерживать xyz, чем в начале метода.

К тому моменту, когда вызывается dealloc, на xyz должно оставаться только одно удержание (что касается объекта myClass), поэтому будет достаточно одного вызова release. Не рекомендуется выпускать, пока retainCount не станет равным нулю, потому что его может использовать другой объект.

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

-(void)dealloc{
    [xyz release];
}
0 голосов
/ 04 февраля 2010
    while([xyz retainCount]==0) 
       [xyz release]; 

Должно быть > 0, иначе -release не будет выполнено. Тем не менее, освобождение xyz, как это плохо, потому что xyz может принадлежать кому-то еще.

Вы должны выделить xyz один и только один раз, и если вы -copy замените xyz, всегда -release старый. Всегда следуйте правилу управления памятью Какао.

Если вам действительно нужно присвоить множественное владение xyz и отдельный целочисленный ivar для записи, сколько раз вы сохранили xyz, значит, у вас есть правильное число -release в -dealloc.

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