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;
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/