L'utilisation de (id) en Objective-C
J'ai une fonction que je veux faire fonctionner sur deux différents objets personnalisés. Ma première pensée a été d'accepter l'argument (id) et d'opérer sur l'id de l'objet. Je ne peux pas tout à fait semblent de comprendre comment le faire, cependant.
Les deux classes (dit des pommes et des oranges) ont d'interface variables:
NSDecimalNumber *count;
Je veux faire quelque chose de similaire à ceci:
-(NSDecimalNumber*)addCount:(id)addObject{
return [count decimalNumberByAdding:addObject.count];
}
Je n'arrive pas à trouver la syntaxe pour faire qui se produisent. Est-ce la bonne approche, ou serait-il préférable de sous-classe (par exemple un fruit de la classe) et d'opérer sur la classe parent?
-(NSDecimalNumber*)addCount:(Fruit*)addFruit{
return [count decimalNumberByAdding:addFruit.count];
}
OriginalL'auteur Jason George | 2009-07-30
Vous devez vous connecter pour publier un commentaire.
Tandis que vous pouvez envoyer un message à n'importe quel objet (id) - les accesseurs de propriété exiger que le compilateur être conscient du type face - c'est parce que les accesseurs de propriété sont sucre syntaxique autour de l'appel spécifique getter et setter.
Vous avez un peu de façons de travailler autour de cela:
Au lieu d'accéder à la propriété count, appeler le correspondant [getCount] les méthodes.
Si les différentes classes ont des versions différentes de cette méthode, vous pouvez utiliser un moteur d'exécution de vérification de type:
Fournir une classe de base pour les deux types de sorte que vous pouvez passer à quelque chose de plus spécifique que (id).
Exemple d'une dynamique de contrôle de type:
Personnellement, je préfère taper fort dans mon code car il est plus facile de comprendre l'intention. Il permet également à l'IDE de soutien votre effort de codage avec intellisense, analyse statique, et des fonctionnalités de refactoring. Donc, dans votre cas, je voudrais utiliser #3 ou #4 comme une approche - selon que l'héritage est vraiment appropriée pour le problème.
Si vous avez vraiment besoin de taper fort, vous pourriez avoir un meilleur temps avec un statique des langages comme le C++. C'est une honte que les propriétés se comporter de cette manière asymétrique. À tout le moins, il devrait y avoir un compilateur indicateur pour permettre symétrique compilation de comportement entre syntaxe de la propriété et le récepteur de la méthode de la syntaxe.
Obj-C peut être juste comme statiquement typés comme la langue suivante, si vous le souhaitez.
OriginalL'auteur LBushkin
Vous devriez essayer de ne pas accéder aux variables d'instance d'une autre classe.
En Objective-C, il suffit que les deux objets de répondre à la même sélecteur (dire
count
), mais qui serait vous donner un avertissement du compilateur.Il y a deux façons dont vous pouvez vous débarrasser de cet avertissement: soit par le sous-classement d'une commune
Fruit
classe ou en ayant vos deux classes se conformer à un protocole. J'irais avec le protocole:Alors votre méthode peut ressembler à ceci:
Ici, vous dites que votre
addCount
s'attend tout de l'objet qui est conforme à laFruitProtocol
protocole, et peut donc répondre à lacount
sélecteur, de sorte que le compilateur accepte.MYObject *object;
, vous pourrez alors accéder à ses variables d'instance d'une classe avec le->
de l'opérateur. Par exemple, en supposant queMYObject
avait unint
ivar nommécount
, vous pouvez utiliserint myCount = object->count;
pour y accéder. Les protections fournies par@private
, etc, sont de nature esthétique, même dans ObjC2.C'est génial! L'exemple de code fait, il est facile pour moi de mettre en œuvre sans plus creuser. Merci beaucoup!
Vous êtes en droit de paratuberculose, je vais le changer pour "vous ne devez pas". Merci
OriginalL'auteur pgb
Le fait que vous essayez d'accéder à 'addFruit.count' est le problème. La syntaxe à point est uniquement pour les propriétés déclarées avec @property (ou pour les structures). Si vous la changez pour
et ajouter
pour chaque classe, alors qu'il allait travailler. Cependant, vous remarquerez que vous aurez un avertissement disant 'id' ne peut pas répondre pour le compte du message, et à moins que vous pouvez être absolument sûr que les articles envoyés à cette méthode de mettre en œuvre un "comte" de la méthode, c'est une problématique de l'approche.
Je suis d'accord avec pgb. Vous devez définir un protocole, et de déclarer les deux classes pour mettre en œuvre ce protocole. Ceci élimine le problème de ne pas savoir si l'objet de répondre à "compter" ou pas, comme vous avez maintenant un "contrat" de toutes sortes.
Si vous voulez garder la syntaxe à point avec une propriété, vous pouvez le déclarer dans le protocole:
et puis, votre fonction sera:
OriginalL'auteur bobDevil
Vous envoyez le message à compter, ce qui est le comte? id est un pointeur vers n'importe quel type d'objet. Si vous vous attendez à ce que l'objet à avoir un comte de la propriété, alors vous ne devriez être en mesure de passer un Tableau (ou un autre type de restriction).
OriginalL'auteur Gordon Gustafson
Comme je le comprends,
id
n'a pas de méthodes ou variables associées avec elle parce que c'est un pointeur générique qui ne fait pas référence à une classe spécifique. Cette page a quelques bonnes infos sur les numéros si vous faites défiler vers le bas un peu.anObject ce ne sera pas une
count
variable, c'est pourquoi votre première tentative ne fonctionne pas. La création d'une classe de base et en les utilisant en tant que paramètre à la méthode semble être la meilleure idée pour moi.OriginalL'auteur jergason