La Confusion avec en-tête et les fichiers de mise en Œuvre en Objective-C
Tout d'abord, veuillez pardonner l'ahurissant de cette question, mais je ne suis pas à partir d'un C/C++ arrière-plan. Je suis un peu confus au sujet de ce qu'est la différence dans des rôles entre la .h et .m les fichiers quand il s'agit de propriétés.
Je comprends le concept d'interfaces, et je vois que dans le cadre de l' .h fichier est une interface pour la mise en œuvre, mais ce que je ne suis pas clair sur ce:
- Pourquoi propriétés/méthodes définies à l'extérieur de l'accolades {}?
-
Que suis-je définir dans les accolades quand j'écris quelque chose comme ceci:
IBOutlet UITextField *champnombre;
Est-ce une définition d'un champ dans une interface?
-
Quand je suis ajoutant les @des lignes de Propriété à l' .h les fichiers sont ces implémentations réelles de n la propriété d'auto ou tout simplement une interface de modèle? Si c'est le @syntesis la mise en œuvre effective?
Je suppose que ma plus grande confusion semble être que si je veux une propriété que je suis la définition de ce dont j'ai besoin dans trois endroits différents (1) dans les interfaces des accolades, (2) que @biens en dehors de l'appareil et (3) avec @synthèse dans le .m de fichier. Cela semble longue haleine, mais ses beaux-si je peux travailler sur ce que ces trois parties ne.
Acclamations, Chris.
Vous devez vous connecter pour publier un commentaire.
Je vais répondre à vos questions ci-dessous, mais peut-être la meilleure façon d'apprendre ce genre de choses, c'est de lire certains convivial notes destinées pour des gens nouveaux à la langue, comme le Apprendre Objective-C tutoriel plus à cocoadevcentral.
Un exemple
J'aimerais aider à répondre à vos questions avec un exemple (j'aime apprendre par exemple). Disons que vous êtes un professeur écrire un programme qui demande aux élèves un particulier question oui/non, et de garder une trace de la façon dont beaucoup de l'obtenir correcte et combien d'élèves il a demandé.
Ici, il est possible que l'interface de cette classe:
Les trois variables à l'intérieur des accolades sont variables d'instance, et chaque instance de votre classe a ses propres valeurs pour chacune de ces variables. Ce qui est extérieur à l'appareil dentaire, mais avant
@end
est une déclaration d'une méthode (y compris les@property
déclarations).(Side note: pour de nombreux objets, il est utile d'avoir
retain
propriétés, puisque vous voulez éviter la surcharge de la copie de l'objet, et assurez-vous qu'il n'est pas sorti pendant que vous l'utilisez. Il est légal deretain
unNSString
comme dans cet exemple, mais il est souvent considéré comme une bonne pratique à utilisercopier
au lieu deretenir
depuis unNSString*
peut en fait montrer unNSMutableString
objet, qui peut par la suite changer lorsque votre code n'attend que ça de rester le même.)Ce
@property
neLorsque vous déclarez une
@property
, vous êtes en train de faire deux choses:Pour la première, il suffit de savoir que cette ligne:
est essentiellement la même que ceci:
dans l'en-tête. Littéralement, vous déclarez ces deux méthodes; vous pouvez les appeler directement, ou utiliser le point comme un raccourci de les appeler pour vous.
Le "en gros" dans le cadre "essentiellement la même" est l'extra info donnée par des mots-clés comme
nonatomic
etretain
.La
nonatomic
mot clé indique qu'ils ne sont pas nécessairement thread-safe. La communeretain
mot clé indique que l'objet conserve toute valeur de l'ensemble, et les versions précédentes des valeurs qu'ils sont laisser aller.Par exemple:
Si le
@property
déclaration pourquestionStr
avait étéassign
au lieu de cela, puis tous lesmyQuestion.questionStr =
déclarations n'aurait pas fait de modifications à tout pour le conserver compte.Vous pouvez lire un peu plus sur les propriétés ici.
Ce
IBOutlet
etIBAction
neCes sont essentiellement non-op mots qui agissent uniquement comme un moyen de dire à Interface Builder des morceaux de l'en-tête du fichier à y prêter attention.
IBOutlet
littéralement devient une chaîne vide lorsque le compilateur regarde, etIBAction
devient levoid
valeur de retour. Nous avons besoin de travailler avec Interface Builder, mais, si elles sont importantes-mais pas pour le compilateur.Note rapide sur le C et des structs flèche vs dot notation
Par ailleurs, les données de l'Objectif-objet C est très similaire à un C struct. Si vous avez un pointeur vers une struct C, vous pouvez utiliser la flèche de la notation
->
pour faire référence à une partie spécifique de la structure, comme ceci:Cette même syntaxe fonctionne de la même manière en Objective-C:
Mais quand vous faites cela, il est pas appel de méthode qui se passe derrière les coulisses, à la différence de la notation par points. Avec le point, vous appelez l'ouvreur (ou de lecture si il n'y a pas de = après), et ces deux lignes sont les mêmes:
C'est souvent une bonne idée pour éviter la flèche de la notation en faveur de la notation par points, depuis le point vous permet d'appliquer l'état valide, par exemple, que les pointeurs de classe a sont toujours conservées. Vous pouvez même en interdire d'autres de l'aide de la flèche de la notation par la déclaration des variables d'instance comme
@private
; ils peuvent toujours utiliser les getter et setter pour y accéder, si vous déclarez une@property
pour elle.Ce que @synthétiser n'
Maintenant, quand vous obtenez autour de la mise en œuvre de votre classe,
@synthesize
dit quelque chose comme "assurez-vous que le getter et le setter de la mise en œuvre de cette propriété." Il ne pas dire "mettre en œuvre les deux pour moi," parce que le compilateur est assez polis pour vérifier votre propre mise en œuvre de la première, et ne remplissez que les morceaux que vous avez manqués. Vous n'avez pas à utiliser@synthesize
à tous, même si vous utilisez@property
comme s'il en pleuvait-on pourrait toujours, il suffit de fournir vos implémentations pour votre setters et getters, si vous êtes dans ce genre de chose.Vous avez probablement remarqué dans le
Question
interface ci-dessus qu'il y a une propriété qui est pas une variable d'instance (numWrongAnswers
), ce qui est bien parce que vous êtes juste de déclarer des méthodes. Dans l'exemple de code ici, vous pouvez voir comment cela fonctionne réellement:Une chose qui se passe ici est que nous allons simuler une variable d'instance appelée
numWrongAnswers
, ce qui serait de l'information redondante si nous stockées dans la classe. Puisque nous savonsnumWrongAnswers
+numCorrectAnswers
=numTimesAsked
à tout moment, nous avons seulement besoin de stocker deux de ces trois points de données, et nous pouvons toujours penser en termes de l'autre, en utilisant les deux valeurs que nous savons. Le point ici est de comprendre qu'un@property
déclaration est vraiment juste sur la déclaration d'un setter et getter méthode, ce qui correspond généralement à une variable d'instance, mais pas toujours. Le@synthesize
mot-clé par défaut ne correspondent à une variable d'instance, de sorte qu'il est facile pour le compilateur à combler dans la mise en œuvre pour vous.Raisons distinctes
.h
et.m
fichiersPar la manière, le point de l'ensemble de la déclaration de méthodes dans un fichier (le
.h
fichier d'en-tête) et la définition de leur mise en œuvre dans un autre (le.m
ou des méthodes de fichier) est d'aider à découpler le code. Par exemple, si vous ne mettez à jour un.m
fichier dans votre projet, vous n'avez pas à recompiler les autres.m
fichiers, car leur code de l'objet restera la même, - ce qui économise du temps. Un autre avantage est que vous pouvez utiliser une bibliothèque qui comprend uniquement les fichiers d'en-tête et de pré-compilé en code objet, ou encore les bibliothèques dynamiques où vous avez besoin du fichier d'en-tête de sorte que le compilateur est au courant des méthodes existent, mais ces méthodes ne sont même pas liés avec votre fichier exécutable. Ces avantages sont difficiles à apprécier quand vous commencez d'abord le codage, mais juste de la logique de rupture et de l'encapsulation de la mise en œuvre devient utile après un court moment.J'espère que c'est utile!
méthodes sont définies à l'extérieur de l'appareil orthodontique depuis les accolades sont destinés à encapsuler l'état de l'objet, qui peut prétendre ne pas inclure l'instance ou les méthodes de la classe.
Ce que vous définissez dans les accolades sont variables d'instance qui peut être référencé en tant que soi.ivar
L' @bien et @synthétiser les directives simplement le programme d'installation accesseurs pour vous de variables d'instance, de sorte que vous pouvez le faire en faisant de l'auto.ivar = someVar. Donc, en d'autres termes, il met en place la "syntaxe à point" pour vous à utiliser.
et pour répondre à ta question finale: Pour définir une propriété ou d'une variable d'instance, il suffit de déclarer dans votre .h fichier comme une variable à l'intérieur des accolades. Pour la configuration des méthodes accesseur sur la même propriété que vous devez faire les DEUX @bien et @synthétiser.
Eh bien, c'est seulement l'Objectif de la syntaxe du C, les méthodes et les @des biens en dehors de {} et les variables à l'intérieur de {}.
@property est la façon de dire que vous allez écrire des accesseurs et des mutateurs (sorte de l'appliquer), mais vous pouvez écrire des getter/setter, sans les mettre @property. @la propriété est dans .h fichier car sa déclaration. Et pourquoi elle est en dehors de {}, eh bien comme je l'ai dit avant c'est juste la syntaxe, ce que nous pouvons faire?
@synthèse sera en mettre en œuvre des accesseurs et des mutateurs, si vous n'avez pas de synthèse mais vous avez définis @property, vous avez à mettre en œuvre ces accesseurs et des mutateurs par votre main. Et @synthèse est en .m fichier, car sa mise en œuvre.
Quelque chose de plus pour vous de lire sur ce sujet peut être trouvé ici.
http://theocacao.com/document.page/510
Les variables à l'intérieur des crochets de définir les structure physique de votre classe. Ceux sont les véritables variables d'instance qui stockent de l'information.
Les trucs à l'extérieur de l'crochets composent la classe de l'interface des méthodes et des propriétés. Un bien dans et de lui-même ne pas réserver un espace de stockage ou d'affecter n'importe quelle variable — il déclare simplement une interface générique pour accéder à quelque chose. Rappelez-vous qu'une propriété ne doit pas avoir un sous-jacente variable d'instance — par exemple, la totalPrice propriété dans un ShoppingCart classe peut dynamiquement somme les prix de tous les articles dans le panier.
À l'intérieur de la mise en œuvre de fichier, vous dites à la classe comment réellement faire son travail. Pour les méthodes, de toute évidence, vous venez de fournir une mise en œuvre. Pour une propriété, vous pouvez soit fournir accesseur implémentations de vous-même ou demandez à synthétiser les accesseurs pour une variable d'instance.