Цель-C - Когда использовать «я» - PullRequest
49 голосов
/ 05 марта 2010

Это неизмененный код из шаблона Apple Utility Aplication для iPhone:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

 MainViewController *aController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil];
 self.mainViewController = aController;
 [aController release];

 mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;
 [window addSubview:[mainViewController view]];
 [window makeKeyAndVisible];

}

Когда mainViewController назначено aController, указывается ключевое слово self:

 self.mainViewController = aController;

Однако, когда установлен фрейм mainViewController, ключевое слово self не требуется:

 mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;

Если я удаляю ключевое слово self из первого примера, программа вылетает с сообщением:

objc[1296]: FREED(id): message view sent to freed object=0x3b122d0

Если я добавлю ключевое слово self во второй пример, программа будет работать нормально.

Может кто-нибудь объяснить, почему self необходим в первом случае, а не во втором? Я предполагаю, что в обоих случаях mainViewController ссылается на одну и ту же переменную экземпляра.

Ответы [ 2 ]

49 голосов
/ 05 марта 2010

Использование self вызывает «сеттер» вашего класса для вызова этой переменной, вместо непосредственного изменения ivar.

self.mainViewController = aController;

эквивалентно:

[self setMainViewController:aController];

С другой стороны:

mainViewController = aController;

просто изменяет переменную экземпляра mainViewController напрямую, пропуская любой дополнительный код, который может быть встроен в метод setMainViewController UIApplication, например, освобождение старых объектов, сохранение новых, обновление внутренних переменных и т. Д.

В случае, когда вы обращаетесь к фрейму, вы все еще вызываете метод установки:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;

расширяется до:

[[mainViewController view] setFrame:[[UIScreen mainScreen] applicationFrame]];

В идеале, для проверки вашего кода в будущем, вы также должны использовать self.mainViewController (или [self mainViewController]) при получении этого значения. В целом, классы гораздо реже содержат важный код в своих методах «получения», чем их «установщики», но все же возможно, что прямой доступ может что-то сломать в будущей версии Cocoa Touch.

11 голосов
/ 05 марта 2010

ключевое слово self указывает, что вы используете свойство getter / setter вместо прямого доступа к значению. в случае, если вы позволяете получателю / установщику автоматически генерироваться с использованием синхронизации, вы должны использовать self в первом примере, потому что объект сохраняется там, а не просто назначается указателем.

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