Зачем инициализировать объекты, которые будут свойствами окольным путем? - PullRequest
1 голос
/ 01 августа 2009

Какие есть причины делать в три строки то, что можно сделать в одной?

Вот код из developer.apple.com :

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

self.navigationController = aNavigationController;

[aNavigationController release];

... и то же самое в одной строке:

self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

Это кажется чистым, простым и достаточно простым. В прошлом у меня были проблемы с тем, что свойство не сохраняется, в результате чего [освобождение объекта] разрушает объект, когда он не должен был (насколько я могу судить - атрибут retain был установлен). Использование формулы в одну строку работает как денди.

Ответы [ 3 ]

6 голосов
/ 01 августа 2009

Правила управления памятью Objective-C диктуют, что, alloc используя экземпляр объекта, вы являетесь (совместно используемым другими объектами retain it) владельцем этого экземпляра и поэтому должны release UINavigationController, когда вы хотите отказаться от владения, чтобы предотвратить утечку памяти. В среде без сбора мусора (например, на iPhone) это означает балансирование alloc или copy (или методов, которые содержат «alloc» или «copy») с release или autorelease. Ваш второй фрагмент будет тогда

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];

Если вы можете избежать использования autorelease в среде с ограниченным объемом памяти (например, iPhone), лучше использовать явное release. -[NSObject autorelease] добавляет получателя к текущему NSAutoreleasePool, который впоследствии вызовет -release для объектов в пуле «когда-нибудь в будущем». Если вы хотите быть осторожнее с использованием памяти, «некоторое время в будущем» не очень хорошая идея. Таким образом, на iPhone вашим первым примером является стандартное использование.

0 голосов
/ 01 августа 2009

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

Если вы действительно хотите сохранить все это в одной строке, используйте что-то вроде этого:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];

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

0 голосов
/ 01 августа 2009

Большинство свойств типов объектов Objective-C должны быть объявлены с помощью retain или copy в своих объявлениях. Например, вы можете сказать:

@property (retain) UINavigationController * navigationController;

Если это так, автоматически написанная функция setNavigationController вызовет retain для вас, а однострочный будет:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];

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

У вас также могут быть проблемы, если вы вызываете release вместо autorelease.

Надеюсь, это поможет!

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