2010-04-23 16 views
31
  1. Quel est le comportement normal dans Objective-C si vous appelez une méthode sur un objet (pointeur) qui est nul (peut-être parce que quelqu'un a oublié de l'initialiser)? Ne devrait-il pas générer une sorte d'erreur (faute de segmentation, exception de pointeur nul ...)?
  2. Si c'est un comportement normal, existe-t-il un moyen de changer ce comportement (en configurant le compilateur) afin que le programme soulève une sorte d'erreur/exception lors de l'exécution?

Pour clarifier ce dont je parle, voici un exemple.Appeler une méthode sur un objet non initialisé (pointeur nul)

Ayant cette classe:

@interface Person : NSObject { 

    NSString *name; 

} 

@property (nonatomic, retain) NSString *name; 

- (void)sayHi; 

@end 

cette mise en œuvre:

@implementation Person 

@synthesize name; 

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

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

@end 

Quelque part dans le programme que je fais:

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 

Répondre

57

Un message envoyé à un objet nil est parfaitement acceptable en Objective-C, il est traité comme un non-op. Il n'y a aucun moyen de le signaler comme une erreur parce que ce n'est pas une erreur, en fait, il peut être une caractéristique très utile de la langue.

De l'docs:

Envoi de messages à zéro

En Objective-C, il est valable d'envoyer un message à zéro-il n'a tout simplement pas d'effet lors de l'exécution. Il existe plusieurs modèles dans Cocoa qui tirent parti de ce fait . La valeur retournée par un message à zéro peut aussi être valable:

  • Si la méthode retourne un objet, un message envoyé à nil retours 0 (nil), par exemple:

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

    Si l » spouseaPerson est nil, alors mother est envoyé à nil etLa méthoderenvoie nil.

  • Si la méthode renvoie tout type de pointeur, tout scalaire de la taille de l'entier inférieur ou égal à sizeof(void*), un float, un double, un long double, ou un long long, un message envoyé à nil rendements 0 .

  • Si la méthode renvoie un struct, tel que défini par le Mac OS X ABI Fonction Guide d'appel à renvoyer dans registres, un message envoyé à nil retours 0.0 pour tous les champs la structure de données. Les autres types de données ne seront pas remplis avec zéros.

  • Si la méthode renvoie autre chose que la valeur mentionnée ci-dessus types la valeur de retour d'un message envoyé à zéro est indéfini.

+2

Et je ne suis pas au courant d'aucune façon de changer ce comportement. C'est un élément fondamental de la programmation avec Objective-C/Cocoa. Vous apprendrez à l'aimer. –

+0

Lien vers le document dans la réponse est mort (* Page introuvable *). – Pang

6

Une chose que vous devriez être clair est que dans Objective-C, vous n'avez pas appel d'une méthode sur un objet, vous envoyer un message à un objet. L'exécution trouvera la méthode et l'appellera.

Depuis les premières versions d'Objective-C, un message à zéro a toujours été un no-op sûr qui renvoie zéro. Il y a beaucoup de code qui dépend de ce comportement.

12

De l » siteGreg Parker:

Si vous exécutez LLVM compilateur 3.0 (Xcode 4.2) ou version ultérieure

 
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}