39 votes

Pourquoi utiliser id quand on peut simplement utiliser NSObject ?

Je sais que lorsque nous voulons créer un objet de valeur inconnue, nous utilisons id. Cependant, je suis curieux de savoir pourquoi Apple a choisi l'id qui décide de la valeur de l'objet pendant l'exécution, alors que chaque objet est une sous-classe de NSObject. Ainsi, au lieu de id delegate nous aurions pu utiliser NSObject *delegate Quelqu'un sait-il pourquoi ? Merci.

2 votes

NSProxy est une autre classe Root fournie par Cacao.

0 votes

NSObject contient un pointeur, id ne le fait pas. Jetez un coup d'œil à stackoverflow.com/a/19634973/944634

0 votes

Quoi lol ? L'identification est un pointeur d'isa. stackoverflow.com/questions/1990695/

41voto

justin Points 72871

id efface le type et cela revient à dire "cet objet répond à tout sélecteur visible par la traduction". Bien sûr, c'est votre responsabilité de s'assurer que votre programme est correct lorsque vous effacez des types (et aussi lorsque vous les tapez).

Si le type était NSObject alors le compilateur dirait "NSObject ne peut pas répondre à sélecteur "si le sélecteur n'a pas été déclaré dans l'interface de NSObject ou dans les protocoles qu'elle adopte. Dans ce cas, vous pouvez également ajouter un typecast pour le faire correspondre au type attendu.

Avec des types stricts/corrects, le compilateur peut intervenir et vous aider, ce qui est formidable car ObjC est un langage très dynamique.

id est particulièrement utile lorsque vous utilisez (ou construisez) des types de collections. L'ajout d'un objet ne poserait pas de problème à moins de définir un nouveau type Root (qui n'hérite pas de NSObject). Obtenir une valeur de la collection nécessiterait un typecast si nous devions l'utiliser comme autre chose que notre classe de base (NSObject).

Objective-C ne supporte pas les génériques - vous ne pouvez pas, par exemple, déclarer un fichier de type NSArray de NSString s. Vous pouvez remplir un NSArray con NSString et le faire passer par id pour un style d'écriture plus naturel lorsque la sécurité des types n'est pas préservée (à la manière des génériques).

Alors, développons cela avec du code réel.

Exemple A

NSString * string = [array objectAtIndex:0]; // << trust me (via id)
return [string length];
-or-
return [[array objectAtIndex:0] length]; // << trust me (via id)

Exemple B

Et maintenant disons id n'est pas disponible et nous corrigeons tous nos avertissements de compilation parce que c'est la bonne chose à faire :

NSString * string  = (NSString*)[array objectAtIndex:0]; // << typecast == trust me
return [string length];
-or-
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me

id ne décide pas de sa valeur au moment de l'exécution, pas plus que les NSObjects. Les objets ObjC n'effectuent pas de promotion implicite, ils transmettent simplement le pointeur sans promotion formelle.

En ce qui concerne votre exemple, je déclare en fait mes délégués et mes paramètres comme des NSObjects avec des protocoles :

NSObject<MONShapeDelegate>* delegate;

0 votes

Cela peut différer dans d'autres compilateurs que ceux que j'ai utilisés, mais pour autant que je sache, si vous déclarez un type comme NSObject<SomeProtocol>, le compilateur supposera que l'objet implémente toutes les méthodes de SomeProtocol, même celles qui sont optionnelles.

0 votes

@Aberrant si une méthode déléguée est facultative, c'est à l'administrateur de l'entreprise qu'il revient d'en décider. appelant pour vérifier que l'objet répond au sélecteur.

0 votes

Je sais, c'est pourquoi j'ai dit que le compilateur suppose qu'ils sont implémentés. Si ce n'était pas le cas, les optionnels provoqueraient toujours des avertissements, car le compilateur ne peut pas être sûr que les objets répondront au moment de l'exécution.

12voto

Jasarien Points 35353

chaque objet est une sous-classe de NSObject

Cette affirmation est incorrecte. Vous pouvez créer des objets qui n'héritent pas de NSObject. Ce n'est pas vraiment recommandé, mais c'est possible.

NSProxy est un exemple - il n'hérite pas de NSObject.

3 votes

C'est juste un clone de ma réponse !

1 votes

Si c'est une pile et que cette réponse est en bas, alors @Jasarien a répondu en premier ;)

0 votes

@beryllium Je ne suis pas sûr de l'ordre des réponses, mais je suis sûr d'avoir répondu en premier.

3voto

9dan Points 2378
typedef struct objc_object {
    Class isa;
} *id;

Ci-dessus se trouve la définition actuelle de l id en langage Objective-C. Le système d'exécution d'Objective-C est construit autour de id y Class . Rien n'a à voir avec NSObject ou la super classe commune.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW3

La classe NSObject

NSObject est une classe racine, et n'a donc pas de superclasse. Elle définit le cadre de base des objets Objective-C et de leurs interactions. Elle confère aux classes et aux instances de classes qui en héritent de se comporter comme des objets et de coopérer avec le système d'exécution. d'exécution.

Une classe qui n'a pas besoin d'hériter d'un comportement particulier d'une autre classe. doit néanmoins devenir une sous-classe de la classe NSObject. Les instances de la classe doivent au moins pouvoir se comporter comme des objets Objective-C à l'exécution. objets Objective-C au moment de l'exécution. Cette capacité a été héritée du NSObject est beaucoup plus simple et beaucoup plus fiable que de la réinventer dans une nouvelle définition de classe.

Je pense que c'est parce que c'est à l'origine C no C++ (ou d'autres langages de typage plus stricts).

1voto

James Webster Points 16663

tout objet est une sous-classe de NSObject

Ce n'est pas correct. Vous pouvez créer un objet qui s'étend à partir de rien comme une classe racine.

C'est peut-être pour cela que l'id a été introduit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X