Les bases du C restant encore dans votre mémoire, il est temps de vous familiariser avec Objective-C. La principale différence avec C est qu'Objective-C est un langage de programmation orienté objet, tandis que C est un langage de programmation procédural. Cela signifie que nous devons d’abord comprendre les objets et leur relation avec les classes. Les autres concepts clés que nous allons explorer dans cet article sont la messagerie d'objet, l'encapsulation et l'héritage..
Objective-C et Cocoa sont deux composants clés de la plate-forme iOS. Malgré le fait que la plate-forme iOS soit encore relativement jeune, Objective-C a été créé au début des années 1980 par Brad Cox et Tom Love chez StepStone. Le langage a été créé dans le but de combiner le langage de programmation C robuste et agile avec l’élégant langage Smalltalk. Objective-C est un sur-ensemble strict de C et, contrairement à C, il s’agit d’un langage de programmation de haut niveau. La principale différence entre C et Objective-C est que ce dernier est un langage de programmation orienté objet, alors que C est un langage de programmation procédural..
Comment iOS a-t-il fini par utiliser un langage développé dans les années 1980? Peu de temps après sa création par Steve Jobs, NeXT a octroyé une licence à Objective-C de StepStone. NeXT a créé NeXTSTEP, un kit d’interface utilisateur pour le système d’exploitation NeXT développé en Objective-C. Bien que NeXTSTEP fournisse un ensemble d'outils révolutionnaire, le système d'exploitation NeXT n'a que peu de succès sur le marché. En 1996, Apple a acquis NeXT et NeXTSTEP est devenu Cocoa. Ce dernier est devenu populaire avec l'introduction d'OS X en mars 2001 et plus tard avec la sortie de l'iPhone et du système d'exploitation iOS.
En programmation procédurale, un programme se compose de une série de procédures ou de routines qui sont exécutés pour atteindre un état particulier. En programmation orientée objet, cependant, une collection d'objets interagissent et travaillent ensemble pour terminer une tâche. Même si le résultat final peut être identique, la méthodologie et les paradigmes sous-jacents sont très différents. La modularité et la réutilisabilité du code sont deux des principaux avantages des langages de programmation orientés objet comme nous le verrons bientôt.
Les nouveaux développeurs dans les écosystèmes iOS et OS X sont souvent déconcertés par la relation entre Objective-C, Cocoa (OS X) et Cocoa Touch (iOS). Qu'est-ce que Cocoa Touch et quel est son rapport avec Objective-C? Cocoa est l'interface de programmation d'application (API) native d'Apple pour les plates-formes iOS et OS X. Objective-C est le langage qui alimente le cacao. Bien que cet article se concentre principalement sur le langage de programmation Objective-C, nous allons examiner de plus près les API de Cocoa et Cocoa Touch plus loin dans cette série..
La distinction entre classes, objets et instances est un autre obstacle pour les développeurs qui débutent dans la programmation orientée objet. Une classe est un cast ou un modèle pour la création d'objets, alors que les instances sont des occurrences uniques d'une classe. Un objet est une structure de données qui a un état et un comportement. Malgré la différence subtile entre les objets et les instances, les deux termes sont souvent utilisés de manière interchangeable.
Prenons un exemple: les grille-pain. Avant la fabrication d'un grille-pain, les ingénieurs créent un plan, équivalent à une classe. Chaque grille-pain créé à partir du plan directeur est une instance ou une occurrence unique de la classe. Même si chaque grille-pain est créé à partir du même modèle (classe), ils ont chacun leur propre état (couleur, nombre d'emplacements, etc.) et leur comportement..
L'état d'une instance est stocké dans et défini par ses variables d'instance, ou les attributs de l'objet si vous voulez. Cela nous amène à un autre motif clé de la programmation orientée objet: encapsulation. L'encapsulation signifie que la représentation interne d'un objet est privée et connue uniquement de l'objet. Cela peut sembler une restriction sévère à première vue. Cependant, le résultat est un code modulaire et faiblement couplé.
Illustrons l’encapsulation avec un autre exemple. La vitesse d'une voiture est mesurée par les éléments internes de la voiture, mais le conducteur connaît la vitesse de la voiture en regardant l'indicateur de vitesse. Le conducteur n'a pas besoin de connaître ou de comprendre les éléments internes de la voiture pour connaître sa vitesse. De même, le conducteur de la voiture n'a pas besoin de comprendre le fonctionnement des moteurs pour pouvoir conduire la voiture. Les détails du fonctionnement d'une voiture sont cachés au conducteur. L'état et le comportement de la voiture sont cachés au conducteur et sont accessible via l'interface de la voiture (volant, pédale de frein, tableau de bord, etc.).
Un autre paradigme puissant de la programmation orientée objet est héritage de classe. Quand la classe A est un sous-classe de classe B, la classe A hérite des attributs et du comportement de la classe B. On dit que la classe B est la classe ou la super-classe parente de la classe A. L'héritage favorise également la réutilisation du code et la modularité..
Les méthodes sont des sous-routines associées à une classe et définissent le comportement d'une classe et de ses instances. Les méthodes d'une classe ont accès aux éléments internes d'une instance et peuvent ainsi modifier l'état de l'instance. En d’autres termes, l’état d’une instance (c’est-à-dire le variables d'instance) est contrôlé par les méthodes d'une instance (c'est-à-dire le méthodes d'instance).
En raison du modèle d'encapsulation, les variables d'instance d'une instance de classe ne sont pas librement accessibles. Au lieu de cela, ils sont accessibles via Getters et les setters, méthodes ayant pour seul but d’obtenir et de définir des variables d’instance. Les propriétés sont une fonctionnalité d'Objective-C qui rend la création d'accesseurs (getters et setters) triviale. Malgré l'utilité des accesseurs, il devient rapidement fastidieux d'écrire des méthodes d'accesseur pour chaque variable d'instance. Nous explorerons les propriétés plus en détail plus tard dans cet article. Pour le moment, considérez les propriétés comme des enveloppes autour de variables d'instance facilitant l'utilisation des variables d'instance via des getters et des setters..
Mettons nos connaissances en pratique en créant un nouveau projet Xcode avec lequel travailler. Créez un nouveau projet dans Xcode en sélectionnant Nouveau> Projet… du Fichier menu.
Comme nous l’avions fait dans l’article précédent, sélectionnez le Outil de ligne de commande modèle de projet dans le Application catégorie sous la OS X section.
Met le Nom du produit à Livres et donnez au projet un nom d'organisation et un identifiant d'entreprise. Pour ce projet, il est important de définir le type de projet sur Fondation. La raison de ce choix deviendra claire plus tard dans cet article.
Indiquez à Xcode où vous souhaitez enregistrer le projet et cliquez sur le bouton Créer bouton. Vous remarquerez peut-être que le projet est différent du projet que nous avons créé pour l'apprentissage C. Prenons un instant pour voir quelles sont les différences..
Le projet contient quelques fichiers et dossiers de plus que l'outil de ligne de commande que nous avons créé dans l'article précédent. En plus de main.m et Livres.1, il y a deux nouveaux dossiers, Fichiers de support et Cadres, chacun contenant un article.
Fichiers de support contient un fichier nommé Livres-Préfixe.pch. le .pch extension de fichier nous dit que c'est un fichier d'en-tête précompilé. Son but deviendra clair plus tard dans cette série.
le Cadres Le dossier contient les cadres auxquels le projet est lié. Qu'est-ce qu'un cadre? Une infrastructure est un ensemble ou un répertoire contenant une bibliothèque, y compris ses ressources, telles que des images et des fichiers d’en-tête. Le concept d'un fichier d'en-tête deviendra clair dans une minute. le Cadres dossier contient actuellement un élément, Foundation.framework.
Lors de la création du projet, vous définissez le type de projet sur Fondation, ce qui signifie que le projet est lié au cadre de la Fondation. Le framework Foundation est un ensemble fondamental de classes Objective-C. Plus tard dans cette série, nous examinerons de plus près le cadre de la Fondation..
Il est temps de créer votre premier cours. Chaque fois que vous créez un nouveau fichier (Fichier> Nouveau> Fichier… ), une liste de modèles de fichiers vous est présentée. Choisir Cacao du OS X section et sélectionnez le Classe Objective-C modèle pour créer une nouvelle classe Objective-C. Cliquez sur Suivant continuer.
Nommez la nouvelle classe Livre
et mettre sa sous-classe à NSObject
. Comme nous l’avons vu précédemment, en faisant de la nouvelle classe une sous-classe de NSObject
, la nouvelle classe héritera des attributs et du comportement de NSObject
. Cela signifie que la nouvelle Livre
classe obtient des fonctionnalités gratuitement.
Cliquez sur Suivant continuer et indiquer à Xcode où vous souhaitez enregistrer la nouvelle classe. Assurez-vous de sauvegarder la nouvelle classe quelque part dans votre projet Xcode..
Xcode a ajouté deux nouveaux fichiers au projet, Livre.h et Livre.m. Livre.h est le fichier d'en-tête du Livre
classe et expose l'interface de classe comme nous l'avons vu plus tôt. Une interface de classe contient les propriétés et les méthodes de la classe. Elle spécifie également la superclasse de la classe.. Livre.m est le fichier d'implémentation de la classe et définit son comportement en implémentant les méthodes déclarées dans le fichier d'en-tête de la classe.
Ouvrir Livre.h et explorer son contenu. À part quelques commentaires en haut, le fichier d’en-tête ne contient que trois lignes de code. La première ligne importe le fichier d'en-tête du framework Foundation. Cela garantit que le Livre
la classe a accès aux classes et protocoles déclarés dans le framework Foundation.
#importation
La deuxième et la troisième ligne forment une paire. En Objective-C, chaque interface de classe commence par @interface
et se termine par @fin
, qui sont à la fois des directives de compilation, c’est-à-dire des commandes ou des instructions pour le compilateur. le @interface
la directive est suivie du nom de la classe, d'un deux-points et de la classe super classe-le cas échéant. Comme nous l’avons vu précédemment, la classe ou superclasse parent est la classe dont elle hérite des attributs et du comportement..
@interface Book: NSObject @end
NSObject
est la classe racine de la majorité des classes Objective-C. Les deux premières lettres, NS, se référer à ses origines, NeXTSTEP, comme nous l'avons vu plus haut dans cet article. En héritant de NSObject
, les classes se comportent comme les classes Objective-C et héritent d'une interface basique avec le système d'exécution.
Avant de modifier le Livre
classe, prenons un rapide pic Livre.m, le fichier d'implémentation de la classe. Au lieu d’importer le framework Foundation, le fichier d’implémentation importe le fichier d’en-tête du fichier Livre
classe. Pourquoi est-ce nécessaire? Le fichier d'implémentation doit savoir quelles propriétés et quelles méthodes sont déclarées dans le fichier d'en-tête avant de pouvoir implémenter le comportement (c'est-à-dire les méthodes) de la classe. La déclaration d'importation est suivie de l'implémentation de la classe, indiquée par @la mise en oeuvre
et @fin
.
le Livre
La classe n'est pas très utile dans son implémentation actuelle. Rendez-vous dans le fichier d'en-tête et ajoutez trois propriétés année
, Titre
, et auteur
, et ajoutez une méthode nommée bookInfo
.
Les propriétés sont déclarées avec le @propriété
mot-clé et peut être déclaré n'importe où dans la classe @interface
bloc. le @propriété
mot-clé est suivi du type et du nom de la propriété. N'oubliez pas l'astérisque devant le Titre
et auteur
propriétés, car un objet Cocoa est toujours référencé comme un pointeur.
#importation@interface Book: NSObject @property int year; @property NSString * title; @property NSString * author; - (NSString *) bookInfo; @fin
La déclaration de méthode ressemble légèrement à un prototype de fonction, mais il existe un certain nombre de différences clés. La déclaration de méthode commence par un signe moins, indiquant qu'il s'agit d'une méthode d'instance. Les méthodes de classe sont précédées du signe plus. Le signe moins est suivi du type de retour de la méthode entre parenthèses, une instance de NSString
, et le nom de la méthode. La déclaration de méthode se termine par un point-virgule.
Je suis sûr que vous vous demandez quoi NSString
est et pourquoi il doit être référencé comme un pointeur. le NSString
La classe est membre du framework Foundation. Il déclare l'interface d'un objet qui gère une chaîne immuable. Dans l'article précédent, nous avons vu qu'une chaîne en C peut être représentée par un tableau de caractères et c'est exactement ce que le NSString
la classe fait, il gère un tableau de caractères sous le capot. L'avantage d'utiliser NSString
est-ce qu'il est beaucoup plus facile de travailler avec des chaînes.
bookInfo
Maintenant que nous avons déclaré le bookInfo
méthode dans le fichier d'en-tête de la classe, il est temps de l'implémenter dans le fichier d'implémentation de la classe. Ouvrir Livre.m et ajoutez l'extrait de code suivant quelque part dans le @la mise en oeuvre
bloc. Avant de casser la mise en œuvre de bookInfo
vers le bas, nous devons d’abord parler de la messagerie objet.
- (NSString *) bookInfo NSString * bookInfo = [chaîneNSString stringWithFormat: @ "% @ a été écrit par% @ et publié dans% i", self.title, self.author, self.year]; retour bookInfo;
Nous savons déjà que le comportement d'une classe est défini par ses méthodes. Pour appeler une méthode sur un objet, un message est envoyé à l'objet. Examinez l'extrait de code suivant pour comprendre ce concept. Découpons ligne par ligne. Dans la première ligne, nous déclarons une nouvelle chaîne et lui attribuons une chaîne constante en l'enveloppant de guillemets doubles et en la précédant d'un @
signe.
NSString * string = @ "Ceci est une chaîne de caractères."; int longueur = [longueur de chaîne]; NSLog (@ "La longueur de la chaîne est% i. \ N" longueur);
Dans la deuxième ligne, nous envoyons un message de longueur
à l'occurrence de chaîne. En d'autres termes, nous appelons la méthode longueur
sur l'occurrence de chaîne et la méthode retourne un entier. L'entier est attribué à la longueur
variable de type int
. Dans la dernière ligne, nous enregistrons la variable de longueur dans la console en appelant le NSLog
fonctionner comme nous l'avons vu dans l'article précédent.
Vous ferez beaucoup de messages à des objets, il est donc important de comprendre la syntaxe. Même si la syntaxe semble étrange si vous débutez avec Objective-C, ce n'est pas si difficile à comprendre. Entre les crochets se trouvent l'objet à gauche et le nom du message ou de la méthode à droite.
[message d'objet];
Les méthodes qui acceptent les arguments sont un peu différentes, mais la syntaxe générale est identique. le NSString
La classe, par exemple, a une autre méthode nommée substringFromIndex:
. Les deux points à la fin du nom indiquent que cette méthode accepte un argument. L'appel de cette méthode sur une chaîne ressemble à ceci:
NSString * substring = [chaîne substringFromIndex: 5];
Objective-C est connu pour ses noms de méthode longs et détaillés. Examinez l'exemple suivant, qui inclut un nom de méthode avec plusieurs arguments. Vous devez admettre que le nom de la méthode indique clairement ce que fait la méthode. Le nom de la méthode est divisé en morceaux, chaque morceau acceptant un argument. La messagerie d'objet va vraiment couler une fois que nous commencerons à travailler avec le SDK iOS.
NSString * anotherString = [chaîne stringByPaddingToLength: 5 withString: @ "une chaîne" startingAtIndex: 2];
Avant de poursuivre, nous devons revoir la mise en œuvre de bookInfo
. L'implémentation de la méthode commence par répéter la déclaration de la méthode. Le point-virgule final est remplacé par une paire d'accolades qui enveloppent la mise en œuvre de la méthode. Nous déclarons d'abord une nouvelle chaîne, bookInfo
, et lui assigner une nouvelle chaîne, créée avec les attributs de notre instance de livre (Titre
, auteur
, et année
). À la fin de bookInfo
méthode, nous retournons la nouvelle chaîne, bookInfo
, parce que c'est ce que la méthode attend, une chaîne comme type de retour.
Trois choses nécessitent des éclaircissements. Tout d'abord, la méthode stringWithFormat:
est une méthode de classe et non une méthode d'instance. Nous le savons parce que la méthode est appelée sur la classe elle-même, NSString
, pas sur une instance de la classe. Les méthodes de classe sont courantes dans les langages de programmation orientés objet. Deuxièmement, le spécificateur de format pour un objet est représenté par le @
symbole (précédé du signe de pourcentage). Tous les deux Titre
et auteur
sont des objets-chaînes pour être précis. Troisièmement, le soi
mot-clé fait toujours référence à l'instance de la classe. Dans ce cas, soi
se réfère à la Livre
instance à laquelle la méthode bookInfo
fait parti.
Si vous avez travaillé avec d'autres langages orientés objet, accéder aux variables d'instance dans Objective-C peut être source de confusion. Nous n'accédons pas directement à une variable d'instance lorsque nous écrivons self.title
. Ce n’est rien de plus qu’un raccourci pour [titre personnel]
. Ce dernier signifie que nous utilisons la méthode getter pour demander à l’instance la variable d’instance nommée Titre
. Il en va de même pour la définition d'une variable d'instance. Jetez un coup d'œil à l'extrait de code suivant. Comme vous pouvez le voir, l’utilisation de self.title
n'est rien de plus que du sucre syntaxique.
// Cette affectation… self.title = @ "The Hobbit"; //… est équivalent à… [self setTitle: @ "The Hobbit"];
identifiant
, néant
, et NUL
identifiant
Avant de commencer à utiliser le Livre
classe, je veux parler de quelques mots-clés qui déroutent les gens de temps en temps. Chaque fois que vous souhaitez stocker un objet sans définir explicitement son type, vous utilisez le identifiant
type de données, qui est également le type par défaut pour les déclarations de retour et d'argument pour les méthodes Objective-C.
Le pouvoir et l'utilité de la identifiant
type de données va beaucoup plus loin, cependant. le identifiant
Le type de données est un composant clé du typage dynamique et de la liaison dynamique d'Objective-C. Il est important de comprendre que le identifiant
le type de données ne contient aucune information sur l'objet lui-même autre que le fait qu'il s'agisse d'un objet.
En Objective-C, chaque objet sait à quelle classe il appartient (à travers un est un
variable) et cela est critique. Pourquoi donc? L’un des points forts d’Objective-C est son typage dynamique, ce qui signifie que la vérification du type est effectuée au moment de l’exécution au lieu de la compilation..
Cependant, depuis le identifiant
le type de données n'indique rien au compilateur sur la classe à laquelle appartient l'objet, l'objet lui-même doit fournir cette information au compilateur.
Gardez à l'esprit qu'il est parfaitement acceptable de taper statiquement un objet dans Objective-C en spécifiant explicitement la classe d'un objet au lieu d'utiliser le paramètre identifiant
Type de données.
Cela nous amène à un autre composant essentiel du moteur d'exécution Objective-C, la liaison dynamique. En Objective-C, une différence importante entre les fonctions et les messages est qu'un message et l'objet récepteur ne sont pas unis jusqu'à l'exécution.
Qu'est-ce que cela signifie et pourquoi est-ce important? Cela signifie que la méthode appelée en réponse à un message envoyé à un objet est déterminée au moment de l'exécution, lorsque le message et l'objet sont connus. C'est ce qu'on appelle la liaison dynamique.
néant
et NUL
En Objective-C, le mot clé néant
est défini comme un nul
objet, c'est-à-dire un identifiant
avec une valeur de 0
. Sous le capot, il n'y a pas de différence entre néant
, Néant
, et NUL
, et il est possible d'envoyer des messages à chacun d'eux sans exception..
La convention est d'utiliser néant
pour les objets, Néant
pour les cours, et NUL
autrement. Être capable d'envoyer des messages à néant
, Néant
, et NUL
a des avantages, mais il a aussi des inconvénients. Pour plus d'informations sur néant
, Néant
, et NUL
, jetez un oeil à cette question sur Stack Overflow.
Ouvrir main.m et ajoutez une instruction d'importation pour importer le fichier d'en-tête du Livre
classe. Au lieu d'utiliser des crochets, nous utilisons des guillemets pour importer le fichier d'en-tête du Livre
classe. Les guillemets doubles sont utilisés pour les fichiers locaux, alors que les chevrons sont utilisés pour les inclusions globales, en utilisant le chemin d’inclusion du projet..
#importation#import "Book.h"
Immédiatement en dessous de la NSLog
appel, ajoutez le fragment de code suivant pour créer une instance du Livre
classe.
Book * book1 = [[Book alloc] init]; book1.title = @ "Le Hobbit"; book1.author = @ "JRR Tolkien"; book1.year = 1937;
Dans la première ligne, nous déclarons une variable de type Livre
et l'initialiser. C'est un bon exemple pour illustrer les appels de méthodes imbriquées. La première méthode appelée sur le Livre
la classe est allouer
. Les détails de cet appel ne sont pas importants. L'essentiel est que la mémoire est allouerated pour le nouvel objet et l'objet est créé.
En raison de l'imbrication des appels, le init
La méthode est appelée sur le nouvel objet créé par le allouer
méthode. le init
méthode initialise le nouvel objet, en le configurant et en le rendant prêt à être utilisé. le init
La méthode retourne l'instance et, dans notre exemple, l'assigne à la book1
variable.
Les trois prochaines lignes doivent maintenant être familières. Nous définissons le titre, l'auteur et l'année de publication du nouveau livre..
Créons un autre livre et ajoutons les deux livres à un tableau Objective-C. La création du deuxième livre n'est pas nouvelle. La seule différence est que nous avons utilisé explicitement les paramètres de la classe pour définir les variables d'instance de la nouvelle instance..
Book * book2 = [[Book alloc] init]; [book2 setTitle: @ "La communauté de l'anneau"]; [book2 setAuthor: @ "JRR Tolkien"]; [book2 setYear: 1954]; NSArray * books = [[NSArray alloc] initWithObjects: book1, book2, nil];
Dans la dernière ligne, nous créons une instance de NSArray
, une autre classe du framework Foundation. le NSArray
class est un tableau pouvant stocker une liste ordonnée d'objets. Comme nous l'avons fait avec les instances de livre, nous allouons de la mémoire et initialisons le nouveau tableau.
Au lieu d'appeler init
, cependant, nous appelons initWithObjects:
. initWithObjects:
est un initialiseur désigné, ce qui signifie que c'est un init
méthode avec quelques cloches et sifflets supplémentaires pour faciliter l'initialisation de l'objet.
initWithObjects:
accepte n'importe quel nombre d'objets que vous souhaitez stocker dans le tableau. La liste des objets doit toujours se terminer par néant
.
J'ai déjà mentionné à plusieurs reprises qu'Objective-C est un sur-ensemble strict de C et que nous pouvons combiner librement C et Objective-C. Voyons comment cela fonctionne. Nous commençons par utiliser un simple sinon
instruction pour vérifier si le tableau contient des objets. En envoyant au tableau un message de compter
, il retournera le nombre d'objets qu'il contient.
Si le tableau contient des objets, nous utilisons un pour
boucle pour parcourir les objets dans le tableau. A chaque itération, nous demandons au tableau l'objet à l'index je
et envoyer l'objet-une instance du Livre
classe-un message de bookInfo
. Comme nous l'avons vu plus tôt, bookInfo
retourne une instance de NSString
, que nous connectons à la console.
if ([nombre de livres]> 0) pour (int i = 0; i < [books count]; i++) Book *aBook = [books objectAtIndex:i]; NSLog(@"%@", [aBook bookInfo]);
Je suis sûr que vous êtes un peu dépassé par Objective-C. C'est normal. Même si Objective-C n’est rien de plus qu’une mince couche au-dessus du langage C, il se passe beaucoup de choses.
Bien qu'Objective-C soit plus complet que ce qui est décrit dans cet article, vous connaissez maintenant les bases et êtes prêt à commencer à utiliser le SDK iOS. Dans le prochain article, nous examinerons le SDK iOS et explorerons ses différents composants..