Подтвердить что ты не робот

Objective-C - Когда использовать 'self'

Это немодифицированный код из шаблона Apple Utility Aplication:

- (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 ссылается на ту же переменную экземпляра.

4b9b3361

Ответ 1

Использование self заставляет "setter" вашего класса "вызывать" эту переменную, а не напрямую менять ivar.

self.mainViewController = aController;

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

[self setMainViewController:aController];

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

mainViewController = aController;

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

В случае, когда вы получаете доступ к кадру, вы все еще вызываете метод setter:

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

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

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

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

Ответ 2

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