Техника управления памятью для Objective-C iVars / свойства - PullRequest
1 голос
/ 15 июня 2010

Следующий код делает что-нибудь ненужное?

@interface MyClass {
   NSArray   *myArray;
}

-(void)replaceArray:(NSArray *)newArray;

@implementation MyClass

-(void)replaceArray:(NSArray *)newArray {
   if( myArray )
   {
      [myArray release];
      myArray = nil;
   }

   myArray = [[NSArray alloc] initWithArray: newArray];
}

@end

Что если я внесу следующие изменения:

1) Сделал myArray свойством:

@property (nonatomic, retain) NSArray myArray;

2) Изменил присвоение на:

self.myArray = [NSArray arrayWithArray: newArray];

Позволит ли я удалить условное?

Ответы [ 4 ]

3 голосов
/ 15 июня 2010

Вам вообще не нужно условное;Вы можете отправить сообщение nil (включая release), и ничего не произойдет.Вам также не нужно выделять новый массив;Вы можете retain тот, который передан вам вместо этого.Если вы беспокоитесь о получении NSMutableArray, вы можете сделать копию.Я бы сделал это:

- (void)replaceArray:(NSArray *)newArray
{
    [myArray autorelease];
    myArray = [newArray copy];
}

Или, если вы не хотите использовать autorelease, вы можете сделать:

- (void)replaceArray:(NSArray *)newArray
{
    if (myArray != newArray) {
        [myArray release];
        myArray = [newArray copy];
    }
}
0 голосов
/ 15 июня 2010

Я проголосовал за mipadi, потому что его ответ правильный в контексте вопроса, который вы задали, но почему бы просто не использовать свойство и покончить с replaceArray: в целом:

@interface MyClass {
   NSArray   *myArray;
}

@property (copy) NSArray* myArray;

@end

@implementation MyClass

@synthesize myArray;

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

@end
0 голосов
/ 15 июня 2010

Изображение следующее:

MyClass * myObj;
// init myObj
NSArray * array = [myObj myArray];
[myObj replaceArray:array];

В этом случае myArray и newArray одинаковы, что означает, что вы используете его после его выпуска. Чтобы решить эту проблему, все, что вам нужно сделать, это удалить метод replaceArray: и реализовать свойство как @synthesize myArray. Таким образом, приведенный выше код изменяется на

MyClass * myObj;
// init myObj
NSArray * array = [myObj myArray];
[myObj setMyArray:array];

и ваша проблема решена синтезированной реализацией.

Обратите внимание, что вы устанавливаете свое значение, создавая новый массив:

myArray = [[NSArray alloc] initWithArray: newArray];

если вы хотите именно такое поведение, вам следует изменить определение свойства, чтобы оно копировалось, а не сохранялось:

@property (nonatomic, copy) NSArray myArray;
0 голосов
/ 15 июня 2010

Уже можно избавиться от условного.Если массив равен nil, вы будете отправлять сообщение для nil, что не является опцией.Назначение на ноль в любом случае также бессмысленно.И если вы сделаете это свойство retain, явное освобождение старого значения будет неправильным.

Однако есть один случай, когда этот код не будет работать правильно: когда аргумент является текущим значением.В этом случае вы освободите текущее значение и затем попытаетесь использовать освобожденный объект (который, возможно, уже был освобожден) для создания нового массива.

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