Je suis nouveau dans la programmation Mac / iPhone et Objective-C. En C # et Java, nous avons des "génériques", des classes de collection dont les membres ne peuvent être que du type déclaré. Par exemple, en C #
Dictionary<int, MyCustomObject>
ne peut contenir que des clés qui sont des entiers et des valeurs de type MyCustomObject. Existe-t-il un mécanisme similaire en Objective-C?
Réponses:
Dans Xcode 7, Apple a introduit des «génériques légers» dans Objective-C. En Objective-C, ils généreront des avertissements du compilateur en cas d'incompatibilité de type.
Et dans le code Swift, ils produiront une erreur de compilation:
Les génériques légers sont destinés à être utilisés avec NSArray, NSDictionary et NSSet, mais vous pouvez également les ajouter à vos propres classes:
Objective-C se comportera comme avant avec les avertissements du compilateur.
mais Swift ignorera complètement les informations génériques. (Ce n'est plus vrai dans Swift 3+.)
Interagir avec les API Objective-C
la source
MyClass <Foo: id<Bar>>
, votre code Swift supposera que les valeurs sont le type de votre contrainte, ce qui vous donne quelque chose avec quoi travailler. Cependant, les sous-classes spécialisées deMyClass
verraient leurs types spécialisés ignorés (cela serait considéré comme un génériqueMyClass
). Voir github.com/bgerstle/LightweightGenericsExampleNon, il n'y a pas de génériques en Objective-C à moins que vous ne souhaitiez utiliser des modèles C ++ dans vos propres classes de collection personnalisées (ce que je déconseille fortement).
Objective-C a le typage dynamique comme fonctionnalité, ce qui signifie que le runtime ne se soucie pas du type d'un objet puisque tous les objets peuvent recevoir des messages. Lorsque vous ajoutez un objet à une collection intégrée, ils sont simplement traités comme s'ils étaient de type
id
. Mais ne vous inquiétez pas, envoyez simplement des messages à ces objets comme d'habitude; cela fonctionnera bien (à moins bien sûr qu'un ou plusieurs objets de la collection ne répondent pas au message que vous envoyez) .Les génériques sont nécessaires dans des langages tels que Java et C # car ce sont des langages forts et typés statiquement. Jeu de balle totalement différent de la fonction de frappe dynamique d'Objective-C.
la source
Non, mais pour être plus clair, vous pouvez le commenter avec le type d'objet que vous souhaitez stocker, j'ai vu cela plusieurs fois lorsque vous avez besoin d'écrire quelque chose en Java 1.4 de nos jours) par exemple:
ou
la source
Il n'y a pas de génériques dans Objective-C.
À partir des documents
la source
Apple a ajouté des génériques à ObjC dans XCode 7:
voir ici: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
la source
Cela a été publié dans Xcode 7 (enfin!)
Notez que dans le code Objective C, il s'agit simplement d'une vérification à la compilation; il n'y aura pas d'erreur d'exécution juste pour mettre le mauvais type dans une collection ou l'assigner à une propriété typée.
Déclarer:
Utilisation:
Soyez prudent avec ces
*
art.la source
Les NSArrays génériques peuvent être réalisés en sous-classant
NSArray
et en redéfinissant toutes les méthodes fournies avec des méthodes plus restrictives. Par exemple,devrait être redéfini en
comme
pour qu'un NSArray ne contienne que des NSStrings.
La sous-classe créée peut être utilisée comme remplacement instantané et apporte de nombreuses fonctionnalités utiles: avertissements du compilateur, accès aux propriétés, meilleure création de code et achèvement dans Xcode. Toutes ces fonctionnalités sont à la compilation, il n'est pas nécessaire de redéfinir l'implémentation réelle - les méthodes de NSArray peuvent toujours être utilisées.
Il est possible d'automatiser cela et de le réduire à seulement deux instructions, ce qui le rapproche des langages prenant en charge les génériques. J'ai créé une automatisation avec WMGenericCollection , où les modèles sont fournis sous forme de macros de préprocesseur C.
Après avoir importé le fichier d'en-tête contenant la macro, vous pouvez créer un NSArray générique avec deux instructions: une pour l'interface et une pour l'implémentation. Il vous suffit de fournir le type de données que vous souhaitez stocker et les noms de vos sous-classes. WMGenericCollection fournit de tels modèles pour
NSArray
,NSDictionary
etNSSet
, ainsi que leurs homologues mutables.Un exemple:
List<int>
pourrait être réalisé par une classe personnalisée appeléeNumberArray
, qui est créée avec l'instruction suivante:Une fois que vous avez créé
NumberArray
, vous pouvez l'utiliser partout dans votre projet. Il n'a pas la syntaxe de<int>
, mais vous pouvez choisir votre propre schéma de dénomination pour les étiqueter comme des classes en tant que modèles.la source
Jeter un coup d'œil à:
https://github.com/tomersh/Objective-C-Generics
Il semble que ce soit une sorte de générique du pauvre, en réutilisant le mécanisme de vérification du protocole.
la source
Maintenant, les rêves deviennent réalité - il y a des génériques dans Objective-C depuis aujourd'hui (merci, WWDC). Ce n'est pas une blague - sur la page officielle de Swift:
Et l'image qui le prouve:
la source
Je veux juste sauter ici. J'ai écrit un article de blog ici sur les génériques.
Ce que je veux apporter, c'est que les génériques peuvent être ajoutés à n'importe quelle classe , pas seulement aux classes de collection comme Apple l'indique.
J'ai ensuite ajouté avec succès à une variété de classes car elles fonctionnent exactement de la même manière que les collections d'Apple. c'est à dire. vérification du temps de compilation, complétion du code, permettant la suppression des transtypages, etc.
Prendre plaisir.
la source
Les classes Collections fournies par les frameworks Apple et GNUStep sont semi-génériques en ce qu'elles supposent qu'on leur donne des objets, certains qui sont triables et d'autres qui répondent à certains messages. Pour les primitives comme les floats, les entiers, etc., toute la structure des tableaux C est intacte et peut être utilisée, et il existe des objets wrapper spéciaux pour eux à utiliser dans les classes de collection générales (par exemple NSNumber). De plus, une classe Collection peut être sous-classée (ou spécifiquement modifiée via des catégories) pour accepter des objets de n'importe quel type, mais vous devez écrire vous-même tout le code de gestion de type. Les messages peuvent être envoyés à n'importe quel objet mais doivent renvoyer null si cela ne convient pas à l'objet, ou le message doit être transmis à un objet approprié. Les erreurs de type vrai doivent être détectées au moment de la compilation et non au moment de l'exécution. Au moment de l'exécution, ils doivent être traités ou ignorés. Enfin, Objc fournit des fonctionnalités de réflexion à l'exécution pour gérer les cas délicats et la réponse de message, le type spécifique, et les services peuvent être vérifiés sur un objet avant qu'il ne soit envoyé un message ou placé dans une collection inappropriée. Attention, des bibliothèques et des frameworks disparates adoptent des conventions différentes quant à la façon dont leurs objets se comportent lors de l'envoi de messages pour lesquels ils n'ont pas de réponse de code, donc RTFM. À part les programmes jouets et les builds de débogage, la plupart des programmes ne devraient pas avoir à planter à moins qu'ils ne se trompent vraiment et n'essayent d'écrire de mauvaises données sur la mémoire ou le disque, d'effectuer des opérations illégales (par exemple, diviser par zéro, mais vous pouvez aussi attraper cela), ou accéder ressources système hors limites. Le dynamisme et le temps d'exécution d'Objective-C permettent aux choses d'échouer gracieusement et doivent être intégrés à votre code. (ASTUCE) si vous rencontrez des problèmes de généricité dans vos fonctions, essayez une certaine spécificité. Écrivez les fonctions avec des types spécifiques et laissez le runtime sélectionner (c'est pourquoi ils sont appelés sélecteurs!) La fonction membre appropriée au moment de l'exécution.
la source