2010-04-23 24 views
31
  1. Qual è il comportamento normale in Objective-C, se si chiama un metodo su un oggetto (puntatore), che è pari a zero (forse perché qualcuno ha dimenticato di inizializzare)? Non dovrebbe generare qualche tipo di errore (errore di segmentazione, eccezione puntatore nullo ...)?
  2. Se si tratta di un comportamento normale, esiste un modo per modificare questo comportamento (configurando il compilatore) in modo che il programma sollevi qualche tipo di errore/eccezione durante il runtime?

Per rendere più chiaro di cosa sto parlando, ecco un esempio.Chiamare un metodo su un oggetto non inizializzato (puntatore nullo)

Avere questa classe:

@interface Person : NSObject { 

    NSString *name; 

} 

@property (nonatomic, retain) NSString *name; 

- (void)sayHi; 

@end 

con questa implementazione:

@implementation Person 

@synthesize name; 

- (void)dealloc { 
    [name release]; 
    [super dealloc]; 
} 

- (void)sayHi { 
    NSLog(@"Hello"); 
    NSLog(@"My name is %@.", name); 
} 

@end 

Da qualche parte nel programma faccio questo:

Person *person = nil; 
//person = [[Person alloc] init]; // let's say I comment this line 
person.name = @"Mike";   // shouldn't I get an error here? 
[person sayHi];     // and here 
[person release];     // and here 

risposta

57

Un messaggio inviato a un oggetto nil è perfettamente accettabile in Objective-C, è trattato come un no-op. Non c'è modo di contrassegnarlo come un errore perché non è un errore, infatti può essere una caratteristica molto utile della lingua.

Dal docs:

invio di messaggi a zero

in Objective-C, è valido per inviare un messaggio a zero-semplicemente non ha effetto in fase di esecuzione. Ci sono diversi modelli in Cocoa che approfittano di questo fatto . Il valore restituito da un messaggio a zero può anche essere valida:

  • Se il metodo restituisce un oggetto, quindi un messaggio inviato a nil rendimenti 0 (nil), ad esempio:

    Person *motherInLaw = [[aPerson spouse] mother];

    Se aPerson s' è spousenil, poi mother viene inviato al nil e laIl metodorestituisce nil.

  • Se il metodo restituisce qualsiasi tipo di puntatore, qualsiasi numero intero scalare di dimensione inferiore o uguale a sizeof(void*), un float, un double, un long double, o long long, allora un messaggio inviato a nil rendimenti 0 .

  • Se il metodo restituisce un struct, come definito dalla Guida chiamata funzione di Mac OS X ABI da restituire in registri, poi un messaggio inviato a nil rendimenti 0.0 per ogni campo nel la struttura dei dati. Altri struct tipi di dati non verranno riempiti con zeri .

  • Se il metodo restituisce qualcosa di diverso dal summenzionato valore , il valore restituito di un messaggio inviato a zero non è definito.

+2

e io non sono a conoscenza di alcun modo per cambiare questo comportamento. È una parte fondamentale della programmazione con Objective-C/Cocoa. Imparerai ad amarlo. –

+0

Il collegamento al documento in risposta è morto (* Pagina non trovata *). – Pang

6

Una cosa che si dovrebbe essere chiari su che è in Objective-C, non lo fai chiamata un metodo su un oggetto, si invia un messaggio a un oggetto. Il runtime troverà il metodo e lo chiamerà.

Dalla prima versione di Objective-C, un messaggio a zero è sempre stato un no-op sicuro che restituisce zero. C'è un sacco di codice che dipende da questo comportamento.

12

Da Greg Parker s' site:

Se l'esecuzione LLVM Compiler 3.0 (Xcode 4.2) o versione successiva

 
Messages to nil with return type | return 
Integers up to 64 bits   | 0 
Floating-point up to long double | 0.0 
Pointers       | nil 
Structs       | {0} 
Any _Complex type    | {0, 0}