Objetivo-C – Quando usar ‘eu’

Este é o código não modificado do modelo iPhone ‘Utility Aplication’ da Apple:

- (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]; } 

Quando mainViewController é atribuído a um aController , a palavra-chave self é especificada:

  self.mainViewController = aController; 

No entanto, quando o quadro mainViewController está definido, a palavra-chave self não é necessária:

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

Se eu remover a palavra-chave self do primeiro exemplo, o programa trava com a mensagem:

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

Se eu adicionar a palavra-chave self ao segundo exemplo, o programa será executado corretamente.

Alguém pode explicar por que o self é necessário no primeiro caso, mas não o segundo? Estou assumindo que em ambos os casos mainViewController está se referindo à mesma variável de instância.

Usar self faz com que sua class “setter” para que esta variável seja chamada, ao invés de mudar a ivar diretamente.

 self.mainViewController = aController; 

é equivalente a:

 [self setMainViewController:aController]; 

Por outro lado:

 mainViewController = aController; 

apenas altera a variável de instância mainViewController diretamente, ignorando qualquer código adicional que possa ser embutido no método setMainViewController do setMainViewController , como liberar objects antigos, reter novos, atualizar variables ​​internas e assim por diante.

No caso em que você acessa o quadro, ainda está chamando um método setter:

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

expande para:

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

Idealmente, para self.mainViewController seu código no futuro, você também deve usar self.mainViewController (ou [self mainViewController] ) ao recuperar esse valor também. Em geral, é muito menos provável que as classs tenham um código importante em seus methods “getter” do que seus “setters”, mas ainda é possível que o access direto possa quebrar algo em uma versão futura do Cocoa Touch.

a palavra-chave self indica que você está usando o getter / setter da propriedade em vez de acessar o valor diretamente. no caso de você permitir que o getter / setter seja gerado automaticamente usando a synchronization, você terá que usar self no primeiro exemplo, porque o object é mantido lá, em vez de simplesmente designado pelo ponteiro.