Ce que j'aime vraiment en C #, ce sont les listes génériques. Une liste qui ne peut contenir qu'un seul type d'objets. Existe-t-il quelque chose comme une liste générique dans Cocoa / Objective-C? Pour l'instant, je ne connais que NSArray
qui prendra un pointeur sur n'importe quel objet.
Réponses
Trop de publicités?Le vouloir dans un Cacao application est souvent un signe de faiblesse de conception.
NSArray
est immuable, afin de ne pas "prendre un pointeur vers un objet" et sans doute déjà contient les objets corrects lors de la remise pour vous. Ce que je suppose, vous êtes plus inquiet est un NSMutableArray
où vous pensez que d'autres parties de votre code peut ajouter le mauvais genre d'objet. Mais un coup au Cacao lui-même; il est extrêmement rare d'en exposer une mutable tableau en tant que partie d'une classe de conception.
Au lieu de cela, vous exposent généralement un NSArray
et un couple de méthodes pour modifier ce tableau. Quelque chose le long des lignes de:
@class Foo : NSObject
- (NSArray *)bars;
- (void)addBar:(Bar *)bar;
- (void)removeBar:(Bar *)bar;
@end
Généralement, il s'arrête de mal d'objets insérés en ayant simplement un avertissement du compilateur, et puis, bien sûr, vous pouvez ajouter des assertions dans -addBar:
et -removeBar:
si vous le souhaitez aussi.
Générique NSArrays peuvent être réalisées par un sous-classement NSArray
, et de redéfinir toutes les méthodes fournies avec les plus dures. Par exemple,
- (id)objectAtIndex:(NSUInteger)index
devrait être redéfini dans
@interface NSStringArray : NSArray
comme
- (NSString *)objectAtIndex:(NSUInteger)index
pour un NSArray, ne contiennent que des NSStrings.
À la création de la sous-classe peut être utilisé comme une baisse-dans le remplacement et apporte de nombreuses fonctionnalités utiles: les avertissements du compilateur, l'accès à la propriété, un code de meilleure qualité de la création et de l'achèvement dans Xcode. Tous ces à la compilation des fonctionnalités, il n'est pas nécessaire de redéfinir la mise en œuvre effective - NSArray de méthodes peuvent être utilisées.
Il est possible d'automatiser cette et faire bouillir à seulement deux états, ce qui le rapproche de langages qui prennent en charge les génériques. J'ai créé une automation avec WMGenericCollection, où les modèles sont fournis à titre Préprocesseur C Macros.
Après l'importation du fichier d'en-tête contenant la macro, vous pouvez créer un générique NSArray avec deux déclarations: une pour l'interface et l'autre pour la mise en œuvre. Vous avez seulement besoin de fournir le type de données que vous souhaitez stocker et de noms pour vos sous-classes. WMGenericCollection fournit des modèles pour NSArray
, NSDictionary
et NSSet
, ainsi que leur mutable homologues.
Non, Objective-C n'est pas actuellement en charge paramétrique du typage des éléments d'une collection.
Cependant, ce sujet est plus complexe que la question ou les réponses existantes avouer..
Paramétrique-Typage pour les collections en Objective-C ne serait pas le même que les médicaments Génériques en C#/Java. Par exemple, il est peu probable que vous verrez jamais Objective-C ajouter de la capacité à assurer à chaque objet ajouté à une collection EST un NSArray type ou sous-type. Au lieu de cela, Objective-C pourrait (et OMI) ont la capacité d'assurer à chaque objet dans une collection CONFORME à un protocole/interface. (c'est à dire qu'elle met en œuvre un ensemble de méthodes requises)
Pourquoi?
Objective-C est un langage construit sur le protocole (interface) de compatibilité, PAS de sous-typage des relations. Qui est, les objets sont compatibles si elles ont toutes les bonnes méthodes, nous ne regardons pas ou se soucient de leurs types réels. En fait, en regardant les types réels est une très mauvaise pratique en Obj-C et de manière très découragé. Cette notion est parfois appelé "Duck Typing", parce que si c'charlatans comme un canard, c'est un canard. Nous n'avons pas de soins si elle a littéralement hérité de certains de canard ou pas. Cela vous empêche d'être sellé par quelqu'un elses mise en œuvre de la hiérarchie. - Le résultat est que tant que un objet sortant de la liste a un tirage au sort:: méthode il fonctionne, nous n'avons pas fait attention si c'est une sous-classe de certains JimmyDrawableBase objet.
Non seulement cela rend le code plus réutilisable, mais il encourage également légèrement différente (plus fonctionnelle?) type de décomposition problème, parce que vous ne pouvez pas compter sur les objets dérivent d'une classe de base et ainsi avoir un tas de votre classe de base de la mise en œuvre forcée en eux.
Personnellement, je pense qu'il serait agréable pour l'Obj-C compilateur pour avoir paramétrique de la vérification de PROTOCOLE *CONFORMITÉ*. C'est, pour faire un NSMutableArray qui exige que tous les objets placés en elle conforme à un protocole donné (c'est à dire un ensemble de méthodes requises).
Parfois même ce plus souple sur le protocole de vérification de la conformité est contestée par programmation dynamique les gens, et avec de bonnes raisons. Les programmeurs ont souvent un moyen de la sur-spécification des exigences de conformité.
Par exemple, vous pourriez avoir besoin d'une liste contenant des objets conformes à la NSArray protocole/interface, mais vous pourriez en FAIT seulement appel à deux de ces méthodes. Ce n'est plus-conformité. Quelqu'un qui souhaite stick compatible d'un point dans votre tableau est obligée de mettre en œuvre une tonne de méthodes que vous ne sont en fait pas d'appel, pas encore du moins (voir ci-après).
Go de Google tente de résoudre ce problème en supposant structurel de compatibilité. C'est, si vous appelez draw() sur les objets provenant d'une liste, alors le compilateur assure tout ce qui se passe dans une liste contient une méthode draw (). Si elle ne contient pas une méthode draw (), c'est une erreur de compilateur de le mettre dans la liste. Cela empêche le code de provoquer la même erreur à l'exécution. Le problème, c'est qu'il ne fonctionne que pour l'ensemble du programme de compilation. Si Google-Aller pourrait compilation modulaire Dll (qui ne peut pas), ensuite, il irait dans le problème qu'il n'y a pas une façon pour moi de dire des objets dans la liste nécessité de soutenir une interface spécifique de ces trois méthodes, même si je ne suis pas de les appeler aujourd'hui, parce que je pourrait les appeler à l'avenir.
Entre ces deux solution aime le compromis et la vérité.
Personnellement, je voudrais voir Objective-C ajouter paramétrique protocole de conformité, afin que je puisse demander au compilateur d'assurer le contenu d'une collection spécifique toujours se conformer à un ensemble de protocoles.
Je voudrais également que le compilateur pour m'aider à éviter la sur-conformité. Si je ne suis pas en appelant les méthodes de ces protocoles sur les objets, il doit générer des erreurs/avertissements qui me dit donc. Si je veux les garder dans le protocole, même si je ne suis pas à l'aide, je doit explicitement faire une déclaration pour chaque méthode dans le protocole qu'il "pourrait être utilisé dans l'avenir, de sorte que tous les éléments de la nécessité de fournir maintenant". Ce qui rend le processus de sur-la conformité nécessitent PLUS de travail, au lieu de Java/C#, où il exige moins de travail.