Objective-C – Quando usare ‘self’

Questo è un codice non modificato dal modello “Utility Aplication” di iPhone di 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 viene assegnato a un aController , viene specificata la parola chiave self :

  self.mainViewController = aController; 

Tuttavia, quando il mainViewController del mainViewController è impostato, la parola chiave self non è richiesta:

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

Se rimuovo la parola chiave self dal primo esempio, il programma si blocca con il messaggio:

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

Se aggiungo la parola chiave self al secondo esempio, il programma funziona correttamente.

Qualcuno può spiegare perché il self è necessario nel primo caso, ma non nel secondo? mainViewController che in entrambi i casi mainViewController si riferisca alla stessa variabile di istanza.

L’uso di sé causa il “setter” della class per chiamare questa variabile, piuttosto che modificare direttamente l’ivar.

 self.mainViewController = aController; 

è equivalente a:

 [self setMainViewController:aController]; 

D’altra parte:

 mainViewController = aController; 

cambia semplicemente la variabile di istanza di mainViewController direttamente, saltando qualsiasi altro codice che possa essere incorporato nel metodo setMainViewController di setMainViewController , come liberare oggetti vecchi, conservarne di nuovi, aggiornare variabili interne e così via.

Nel caso in cui accedi al frame, stai ancora chiamando un metodo setter:

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

si espande a:

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

Idealmente, per la dimostrazione futura del codice, dovresti utilizzare anche self.mainViewController (o [self mainViewController] ) anche quando [self mainViewController] questo valore. In generale, le classi hanno meno probabilità di avere un codice importante nei loro metodi “getter” rispetto ai “setter”, ma è comunque ansible che l’accesso diretto possa rompere qualcosa in una versione futura di Cocoa Touch.

la parola chiave self indica che si sta utilizzando la proprietà getter / setter invece di accedere direttamente al valore. nel caso in cui si lasci che il getter / setter venga generato automaticamente usando la sincronizzazione, è necessario utilizzare self nel primo esempio perché l’object viene mantenuto lì invece che semplicemente assegnato dal puntatore.