2015-08-19 2 views
2

Je rencontrais un problème avec la méthode d'une sous-classe qui se faisait appeler pour remplacer une méthode, donc j'ai créé une petite application pour la tester. Lorsque la superclasse appelle une méthode que sa sous-classe écrase, la version de la méthode de la superclasse est appelée à la place de la version de la sous-classe, qui remplace la méthode de la superclasse et devrait être la méthode appelée.Swift appelant la méthode substituée de la sous-classe à partir de la superclasse

Résultats attendus: sub foo

sortie actuelle: super foo

superclasse:

class ViewController: UIViewController 
{ 
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 
    { 
     foo() 
    } 

    func foo() 
    { 
     println("super foo") 
    } 
} 

Sous-classe:

class SubclassViewController: ViewController 
{ 
    override func foo() 
    { 
     println("sub foo") 
    } 
} 
+0

Quelle est la classe de l'objet sur lequel touchesBegan est appelé? Est-ce SubclassViewController ou est-ce ViewController? –

+0

Wow, je me sens stupide. Je n'ai jamais changé le contrôleur de vue initial dans le storyboard pour être un SubclassViewController. Merci. Mettez votre commentaire en réponse. – Aderis

+0

Je suis en train de voir ce problème avec des sélecteurs dans une superclasse, ios 10, Xcode 8 – MobileMon

Répondre

2

Assurez-vous que la classe de l'objet est SubclassViewController. Autrement, il n'aura aucune connaissance de la méthode qui est remplacée par la sous-classe

5

Il est également intéressant de vérifier que vous n'essayez pas de remplacer une extension. Pour une raison quelconque, le remplacement ne peut pas être effectué dans une extension.

2

Je viens de tombé sur cette question dans Xcode 8.1/Swift 3.0

J'ai créé une super classe avec un talon de méthode avec l'intention de celui-ci remplaçant dans ma sous-classe, mais l'appeler de super et à ma grande surprise la override n'a pas été appelé.

Ma solution au problème était de créer un protocole. En utilisant l'exemple de l'OP, ma solution ressemble à ceci:

super:

class ViewController: UIViewController 
{ 
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 
    { 
     foo() 
    } 

} 

Sous-classe:

class SubclassViewController: ViewController 
{ 
    override func foo() 
    { 
     println("sub foo") 
    } 
} 

Protocole:

protocol Fooizer { 
    func foo() 
} 

extension Protocole:

extension ViewController : Fooizer{ 
    func foo(){ 
     abort() //If you don't override foo in your subclass, it will abort 
    } 
} 
+0

Merci Trevis, cela a résolu mon problème. – genalipsis