iphone @property (сохранить), init () и стандарты - PullRequest
1 голос
/ 09 июня 2010

Я новичок в управлении памятью iphone и у меня возник вопрос о стандартах / правильности.

Мой заголовочный файл объявляет:

 IBOutlet UITabBarController *tabBarController;
 @property (nonatomic, retain) UITabBarController *tabBarController;

В моем коде init ()делал что-то вроде следующего:

self.tabBarController = [[UITabBarController alloc] init];
[tabBarController release];
NSLog(@"Retain count of tbc: %d",[tabBarController retainCount]);

, чтобы вернуть счет удержания одному.Это правильно с точки зрения стандартизации?Это выглядело немного по-другому, но опять же я новичок в этом.

Спасибо

Ответы [ 4 ]

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

Это нормально.

Что вы делаете:

self.tabBarController = [[UITabBarController alloc] init];
[tabBarController release];

может быть выполнено компилятором как:

id *tempVar = [[UITabBarController alloc] init];
self.tabBarController = tempVar;                  //till now, retainCount is 2
[tabBarController release];                       //now, retainCount is 1

Когда вы выделите его, этот блок памяти будет сохранен во временной переменной.Поэтому лучший способ сделать это:

UITabBarController *tabCtl = [[UITabBarController alloc] init];
self.tabBarController = tabCtl;
[tabCtl release];

Я не специалист по object-c, просто немного разбираюсь в компиляции.Так что, если я ошибаюсь, эксперты здесь, пожалуйста, укажите.

2 голосов
/ 09 июня 2010

Для присвоения собственности, вы должны использовать

self.tabBarController = [[[UITabBarController alloc] init] autorelease];

или

[tabBarController release];
tabBarController = [[UITabBarController alloc] init];

(не забудьте сначала освободить предыдущее значение)

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

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

[self setTabBarControler:[[UITabBarController alloc] init]];
/* Relying on knowledge of the instance variable is bad here, setTabBarController
   might do something different in the future */
[tabBarController release];

Даже если вы полностью контролируете класс, вы все равно должны придерживаться основных принципов абстракции и инкапсуляции. Оставьте сохранение / освобождение переменных экземпляра для реализации базового свойства.

1 голос
/ 09 июня 2010

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

Просто сделай:

tabBarController = [[UITabBarController alloc] init];
1 голос
/ 09 июня 2010

Почему бы не

tabBarController = [[UITabBarController alloc] init];

?

...