3

Je veux mettre en œuvre une classe UIView mobile (vue se déplace lorsque vous appuyez dessus et déplacez votre doigt), par exemple:a besoin d'héritage multiple en Objective C

@interface MovableView : UIView { 
    some members; 
} 
-touchesBegan; 
-touchesMoved; 
@end 

Comment puis-je appliquer ce code à UILabel, UIButton etc sans héritage multiple? En C++, je ferais comme ça (avec UIView comme base virtuelle MovableView):

struct MovableLabel : UILabel, MovableView {}; 

Les catégories sont proposées comme une alternative à l'héritage multiple, mais je ne veux certainement pas à mesure UIView utilisant des catégories parce que cela s'appliquerait à toutes les vues dans mon application. Je veux seulement que certaines de mes opinions soient mobiles. Ma stratégie actuelle pour éviter la duplication de code est de mettre du code MovableView dans un fichier d'en-tête et de l'inclure à chaque fois que j'ai besoin d'une classe pour l'utiliser. En plus de cela, je dois ajouter des membres de MovableView à n'importe quelle classe que j'écris. C'est de la pure laideur de code mais mieux que copier/coller du code partout dans mon projet.

Est-ce que quelqu'un a d'autres idées pour contourner cette limitation Objective C [de ne pas avoir hérité multiple]?

Merci,

Altan

+0

duplication possible de [héritage multiple dans Objective C] (http://stackoverflow.com/questions/5951388/multiple-inheritance-in-objective-c) – Mark

Répondre

7

Objective-C ne vous laissera pas faire cette chose d'héritage mixin, sauf en ajoutant la même catégorie pour chacune des classes que vous soin d'augmenter. Et puis, vous n'obtiendrez pas de variables d'instance supplémentaires.

Pour votre problème spécifique, je pourrais l'aborder en concevant MovableView comme une classe de conteneur qui était juste un objet qui a une vue enfant (UILabel, UIButton, etc.) que vous voulez déplacer comme sous-vue.

+0

Et il y a une bonne raison pour interdire l'héritage multiple: Dans le vieux temps C++ ces techniques ont causé l'enfer de la dépendance et dans les temps modernes de couplage lâche, vous voulez éviter quelque chose comme l'enfer de la dépendance –

+0

Bonne idée, quixoto. Un peu plus de travail dans Interface Builder mais moins de classes et de codage. – Altan

2

Les catégories ne aideraient pas de toute façon car le remplacement de la vraie méthode touchesBegan sur UIButton serait très mauvais ... vous ne pouvez pas appeler [super] d'une catégorie.

Une autre solution serait d'injecter une méthode dans ces définitions de classe avec quelque chose comme:

Method origMethod = class_getClassMethod([UIButton class], @selector(touchesBegan)); 
Method newMethod = class_getClassMethod([TemplateClass class], @selector(replacementTouchesBegan)); 
method_exchangeImplementations(origMethod, newMethod); 

Mais c'est assez fiddly. Bien que si c'est vraiment où vous voulez aller, il vaut la peine de regarder dans ...

Ce que je ferais est de faire une classe MovableView qui hérite de UIView, et simplement ajouter tout ce que vous voulez mobile comme une sous-vue de cette vue (qui Je pense pourrait être légèrement différent de ce que disait Quichotte, mes excuses si ce n'est pas le cas). Il arrive à répondre aux contacts en premier et transmet tout ce dont il n'a pas besoin au prochain répondant ... pas besoin de créer une classe spéciale avec une seule sous-vue. Ensuite, dans IB, vous pouvez placer ces vues mobiles n'importe où et y placer des objets.

En général, les techniques de composition comme celle-ci sont très utiles sur UIKit plutôt que de modifier les classes de base.