12
votes

Utilisation optimale des fonctionnalités dynamiques de l'objectif-C

J'ai utilisé l'objectif-c pendant un peu de temps, mais d'une base de type statique (C #), je pense que je l'utilise de manière très statique. Déclarant des objets comme Id ID se sent étranger pour moi et je ne vois pas ce que sont les avantages. Quelqu'un peut-il briller une lumière pour moi pour mieux comprendre cela?


0 commentaires

4 Réponses :


3
votes

C'est vraiment rare que vous devez déclarer un objet comme type ID , car vous devez généralement savoir quel type vous attendez. Parfois, vous pouvez utiliser un type ID , si vous ne connaissez pas le type actuel d'un objet, mais sachez qu'il doit être conforme à un protocole spécifique.

Y a-t-il un scénario particulier que vous envisagez?


1 commentaires

J'utilise l'identifiant mais qui me semble fortement tapé et est analogue à l'utilisation d'interfaces dans C #. J'ai vu des gens mentionner que certaines tâches deviennent triviales dans des langues dynamiques, mais elles n'ont jamais donné d'exemples. Je suppose que je veux juste m'assurer que je profite pleinement de la langue et que je ne fais pas de choses plus difficiles pour moi en pensant fortement typé.



2
votes

instance de passage comme ID code> est courant lors de la conception de la méthode de l'action; Connexion d'un bouton à une méthode, la cible ressemble à dosomething: (id) émetteur; code>.

Dans ce cas, il permet à différents types de contrôles d'utiliser la même méthode d'action, sans une connaissance préalable de ce que ces contrôles seront. Dans le code de méthode de l'action, vous pouvez tester la classe de l'expéditeur ou simplement utiliser sa propriété Tag CODE> pour décider quoi faire. P>

-(void) doSomething:(id) sender {
    // Get the sender's tag whatever it is
    int tag = [sender tag]; 
    switch(tag) {
        case 1:
            // ...
            break;
        case 2:
            // ...
            break;
    }
} 


0 commentaires

13
votes

Objective-C est une sorte de langage hybride dans lequel vous pouvez être aussi dynamique et statique que vous le souhaitez. Vous pouvez déclarer tous les types de toutes les variables si vous le souhaitez, vous pouvez même déclarer des variables déléguées comme NsObject * si vous le souhaitez. Le type d'identifiant fonctionne moins comme un type réel et plus comme un indice du compilateur Dites-lui "Hey, je sais ce que je fais, croyez-moi simplement à cela", ce qui fait que le compilateur évite tout type Vérification de cette variable particulière.

Le premier avantage évident du système de type Objective-C est que les types de conteneurs (NSARRAY, NSDictionary, NSSET) acceptent et les types d'identification de retour. Cela supprime le besoin de modèles et de génériques (comme en C ++, Java et C #).

Mieux encore mieux, vous pouvez réellement avoir des conteneurs avec des éléments de n'importe quel type à l'intérieur. Tant que vous savez ce qui se passe à l'intérieur, personne ne se plaindre si vous ajoutez deux nstrings, un nombre NSNumber et une nsvalue à l'intérieur du même Nsarray. Vous pouvez le faire dans d'autres langues, mais vous devez utiliser la classe de base "objet", ou le type de vide *, puis vous avez besoin de la boîte et des variables de boîte (ou de mise en marche) afin d'obtenir le même comportement. Dans l'objectif-C, vous venez d'attribuer, ce qui supprime le bruit généré par les opérateurs de casting et les opérations de boxe. Ensuite, vous pouvez demander à "RépondrstoSelector:" ou "Classe" à chaque objet, afin de connaître l'identité et les opérations que vous pouvez effectuer avec eux, au moment de l'exécution. Dans l'objectif-c, la réflexion est un citoyen de première classe.

Un autre avantage est la réduction des temps de compilation; La compilation d'un programme Objective-C est en général beaucoup plus rapide que son équivalent en C ++, étant donné qu'il n'y a pas que de nombreux contrôles de type effectués et que de nombreuses liaisons sont effectuées au moment de l'exécution. Le compilateur fait confiance davantage au programmeur.

Enfin, le système de type dynamique de l'objectif-C permet d'avoir un outil comme Builder d'interface. C'est la raison principale pour laquelle le cacao et le cacao touch ont des temps de développement plus rapides; L'interface graphique peut générer du code avec des types "ID" partout sur la place et celle-ci est désérialisée chaque fois que la nib est chargée en mémoire. Le seul langage qui s'approche de l'objectif-C en termes d'expérience de conception de l'interface utilisateur est C # (et vb.net, bien sûr), mais au prix d'une application beaucoup plus lourde.

Je préfère personnellement travailler avec une vérification de type plus statique, et j'allume même les paramètres "Traiter les avertissements comme erreurs" dans le compilateur de l'objectif-C; J'ai écrit un article de blog à ce sujet:

http://akosma.com/2009/07/16 / Objectifs-C-compilateur-Avertissements /

Ceci est particulièrement utile lorsque vous travaillez avec des développeurs qui sont nouveaux dans la langue. Il rend le compilateur gémissant le plus souvent que d'habitude :)

Les experts du système de type statique peuvent être en désaccord avec tous ces points, affirmant que la vérification du type statique permet aux IDes "Intellisense" et à une meilleure maintenance en général. J'ai travaillé en utilisant .NET pendant des années (2001 - 2006) et je dois dire que les langues dynamiques ont tendance à produire moins de code, sont plus faciles à lire et, en général, donne plus de liberté au travail. Le compromis (il y a toujours un compromis) est qu'il y a moins d'informations au moment de la compilation. Mais comme j'ai tendance à dire, Les compilateurs sont la suite de tests d'un homme pauvre. La meilleure chose à faire est d'avoir une bonne suite de tests, et un bon groupe de testeurs humains torturant votre code pour trouver des bugs, Peu importe la langue que vous choisissez.


1 commentaires

Merci @akosma pour prendre le temps d'écrire cette excellente réponse. :RÉ



5
votes

Le dynamisme de l'objectif-C brille non seulement dans le fait que chaque objet est un ID . Il brille plutôt dans la puissance de l'exécution de l'objectif-C et de la facilité à l'utiliser. Quelques exemples d'utilisations intelligentes d'exécution par pomme elle-même:

Do vous permet de configurer Un objet proxy pour un objet obj-c dans une application distincte / distincte. Ceci est fait en interceptant tout le message envoyé à l'objet proxy, en l'emballant, envoyez-le à l'autre application et l'invoquant là-bas.

kvo est mis en œuvre en remplaçant dynamiquement la méthode Setter afin qu'elle notifie automatiquement les observateurs. (Eh bien, c'est en fait subtiliser que cela ...)

Les accesseurs de Coredata sont générés au moment de l'exécution pour chaque sous-classe de nsmanagedObject , etc.

Et, vous pouvez utiliser le Runtime de votre code , trop. Une fois, je l'ai utilisé une fois pour un bon effet, imitant la Coredata et générer des accesseurs au moment de l'exécution et n'ayant que sa déclaration dans le fichier d'en-tête. Ainsi, vous pouvez obtenir le mérite de la typographie statique (erreur de compilation de la Déclaration de la déclaration dans l'en-tête) et du dynamisme (génération d'exécution de méthodes).

Mike Ash a écrit une excellente série de publications de blog sur la manière dont l'exécution fonctionne et comment l'utiliser efficacement. Vous devez juste le lire! Faire , KVO , transfert de message et plus . Il existe également de nombreux autres postes intéressants sur le Net, comme amusant avec KVC et messagerie à commande supérieure < Un href = "http://www.cocoadev.com/index.ploadev.com/index.pl?higherordermessaging" rel = "noreferrer"> 1 , 2 .


0 commentaires