2009-07-26 3 views
0
  1. Lors de l'initialisation d'un tableau NSMutableArray avec un objet, Pourquoi mettre nil à la fin?Quelques questions sur Objective-C, Cocoa et Xcode

    par exemple.

    NSMutableArray *fruits = [[NSMutableArray alloc] initWithObjects:apple, 
                       watemelon, 
                       nil]; 
    
  2. Dans Xcode, lors de l'utilisation de l'auto-complétion pour remplir les variables de fonction. Quelle est la touche de raccourci pour passer à la variable suivante?

    par exemple:

    Fruit *fruit3 = [[Song alloc] initWithName:(NSString *)n 
               description:(NSString *)d  
    

    je tape la fonction initWithName et complète automatique. Donc, je presse l'onglet tout de suite pour arriver à n, après avoir terminé cela, comment puis-je obtenir à d?

  3. Si j'ai un tableau de fruits avec des objets de fruits comme dans la question 1. L'objet de fruit étant une sous-classe NSObject. Pourquoi avoir la "copie" dans la déclaration @property pour la propriété name dans ma classe Fruit.

    Lorsque je sais que par défaut l'objet fruit va résider dans son propre espace mémoire. Depuis que je crée un pointeur de fruits. Fruit *apple = [[Fruit alloc]....

  4. NSString *a = @"Hello Everyone";

    Qu'est-ce que le @"" faire?

    -t-il faire quelque chose comme ceci:

    [[NSString alloc] initWithValue:"ok"]; 
    

Répondre

8
  1. La méthode est implémentée à l'aide des listes d'arguments variables (... dans la déclaration fonction C) en C le nombre de paramètres dans ce cas est inconnu. Vous devez donc fermer la liste avec une valeur nulle (0).
  2. Control-/
  3. Parce qu'un NSArray est un tableau de pointeurs. Si vous affectez le tableau sans le copier, d'autres objets (qui référencent le tableau) peuvent modifier le tableau. Avec la copie, vous êtes sûr que les éléments du tableau ne seront pas modifiés en dehors de votre classe.
  4. La structure @ "xyz" retournera une NSString auto-libérée. Ce sera donc quelque chose comme [[[NSString alloc] initWithUTF8String: "xyz"] autorelease].
+0

thx..parfaites réponses – user145374

+3

Notez que dans le Snow Leopard XCode, vous pouvez simplement faire un tabulation entre les paramètres complétés. –

+0

La réponse 3 n'est pas claire ici. Vous suggérez que "copier" empêche les changements dans les éléments en faisant une copie en profondeur, mais ce n'est pas vrai du tout et je doute que ce soit ce que vous voulez dire. La raison de 'copier' est d'empêcher les changements au tableau lui-même - empêcher les objets d'être ajoutés/retirés derrière votre dos. Vous en avez besoin même si votre propriété est un NSArray *, car le tableau transmis peut toujours être un tableau mutable. – Caleb

4
  1. arguments variables dans C (et donc, en Objective-C) sont très primitive. La méthode obtient seulement un pointeur vers la pile, et doit avoir un mécanisme pour établir les types et le nombre de paramètres. Pour printf et similaires, il s'agit de codes de format; pour -initWithObjects: c'est une sentinelle, c'est-à-dire une valeur connue indiquant la fin de la liste, dans ce cas nul.
  2. Préférences-> Liaisons de touches-> Liaisons de touches de texte-> Code Sense Sélectionnez Next Placeholder.
  3. Considérez ce qui suit:
NSMutableString *str = [NSMutableString stringWithString:@"Fred"]; 
fruit.name = str; // Legal; NSMutableString is a subclass of NSString 
[str setString:@"Barney"];

Si fruit.name est pas déclaré une propriété de copie, la dernière ligne va changer le nom du fruit (depuis fruit.name et str font référence au même objet). Si c'est une copie déclarée, ils seront des objets séparés. (Cependant, si vous utilisez un objet simple NSString, aucune copie ne sera faite car NSString s sont immuables et il n'y a aucun problème à se référer au même objet

+0

votre analogie pour le numéro 3 a rendu limpide thx beaucoup – user145374

3

Voici une explication plus complète de la question 1. C et Objective-C sont plutôt des langages de plus bas niveau par rapport à des langages tels que Java, C#, Python, Ruby et autres.En C et Objective-C, fonctions avec un nombre variable d'arguments (varargs ou variadic fonctions) sont autorisés, mais le langage ne fournit aucun mécanisme pour connaître le nombre d'arguments effectivement transmis. Les langages de niveau supérieur fournissent généralement cela en exposant les arguments supplémentaires sous forme de liste ou de tableau d'objets: C et Objective-C utilisent un ensemble plus limité de macros pour accéder à l'extra arguments un à la fois. Par conséquent, toute fonction variadique nécessite une autre méthode pour déterminer le nombre réel de paramètres transmis. Les familles de fonctions printf et scanf utilisent une chaîne de format comme l'un des paramètres fixes, et les spécificateurs de format trouvés dans la chaîne de format indiquent le nombre et les types d'arguments supplémentaires passés. Le message -initWithObjects: de la classe Objective-C D'autre part, NSMutableArray requiert la fin de la liste des arguments supplémentaires avec nil. Par conséquent, vous ne pouvez pas passer en argument nil (puisqu'il marquerait la fin de la liste des arguments), mais cela est correct dans ce cas puisque NSMutableArray s spécifient qu'ils ne peuvent pas contenir d'objets nil. Sur l'architecture x86, les fonctions variadiques sont implémentées en utilisant la convention d'appel C (cdecl), par laquelle les arguments sont poussés sur la pile de droite à gauche. L'appelant est responsable du nettoyage de la pile après l'appel. Ainsi, un appel à printf() pourrait se compilé dans quelque chose comme ceci:

// ignore the fact that these are invalid calls to printf 
printf("format string 1", a1, a2); 
printf("format string 2", b1, b2, b3); 

// The above might get compiled into this: 
push a2 
push a2 
push <address of "format string 1"> 
call printf 
add $12. %esp // restore stack pointer to offset the pushes 
push b3 
push b2 
push b1 
push <address of "format string 2"> 
call printf 
add $16, %esp // restore stack pointer 

La raison pour laquelle les arguments sont poussés de droite à gauche au lieu de gauche à droite est que la pile grossit vers le bas - la x86 push instruction décrémente le pointeur de pile esp par 4 octets. Ainsi, lorsque la fonction appelée examine la pile, elle verra les arguments dans le bon ordre. Immédiatement après le premier appel à printf ci-dessus, la pile ressemble à ceci:

 
%esp+0x00: return address to calling function 
%esp+0x04: address of "format string 1"> 
%esp+0x08: a1 
%esp+0x0c: a2 
%esp+0x10 and above: local variables from calling function, rest of stack 

Lorsque la fonction appelée examine ses arguments, il marche juste la pile, mais il ne sait pas où arrêter - la convention d'appel ne précise pas combien d'arguments il y a. La fonction doit juste savoir par d'autres moyens. La plupart des fonctions ont un nombre fixe de paramètres, ce qui leur est facile, mais les fonctions variées ont besoin d'un autre moyen pour déterminer le nombre exact de paramètres.

S'il existe un décalage entre le nombre de paramètres que la fonction pense avoir reçus et le nombre de paramètres réellement transmis (par exemple, une chaîne de format incorrect a été transmise à printf), le résultat est incorrect. Le cas le plus probable est que la fonction continuera à lire la pile, et vous obtiendrez des valeurs de déchet quelque part. Pire, votre programme pourrait tomber en panne.Pire encore, votre programme peut sembler fonctionner normalement, mais vous avez peut-être ouvert par inadvertance un trou de sécurité.

Questions connexes