J'ai une extension:
public extension UIWindow {
override public func topMostController()->UIViewController? { ... }
}
mais pour mon topMostController
j'obtiens l'erreur suivante:
Declarations in extensions cannot override yet error
Cela fonctionne bien pour Swift 3.1, mais pour Swift 4, je reçois cette erreur. Comment peut-il être corrigé? Qu'ont-ils changé en Swift 4?
Cela fonctionnera si vous faites l'implémentation de base @objc
. Voir réponse de Hamish pour une explication détaillée sur les composants internes.
Remplacer les méthodes déclarées dans les extensions est un peu délicat à faire correctement. Objective-C le soutient, mais ce n’est pas absolument sûr. Swift vise à le faire mieux. La proposition n'est pas encore terminée.
Version actuelle de la proposition disponible ici .
Les extensions peuvent ajouter de nouvelles fonctionnalités à un type, mais elles ne peuvent pas remplacer les fonctionnalités existantes.
Les extensions ajoutent de nouvelles fonctionnalités à une classe, une structure, une énumération ou un type de protocole existant. Cela inclut la possibilité d'étendre des types pour lesquels vous n'avez pas accès au code source d'origine (connu sous le nom de modélisation rétroactive).
Les extensions dans Swift peuvent:
Vous essayez de faire est similaire à ce que fait par ce code:
class MyClass: UIWindow {
func myFunc() {}
}
extension MyClass {
override func myFunc() {}
}
NOTE: Si vous voulez override topMostController()
, créez une sous-classe de UIWindow
En fait, il y a peu de problèmes dans le code OP:
UIView
(qui est la super-classe de UIWindow
) n'a pas de méthode topMostController()
, c'est pourquoi vous ne pouvez pas la remplacer.
Apple n'encourage pasoverride func
à l'intérieur extension
:
Les extensions peuvent ajouter de nouvelles fonctionnalités à un type, mais elles ne peuvent pas remplacer les fonctionnalités existantes.
Si vous souhaitez toujours remplacer une fonction dans une extension, il existe deux méthodes:
[A] Marquez votre fonction avec @objc dynamic func
dans la classe parente:
class Vehicle {
@objc dynamic func run() { /* do something */ }
}
class Car: Vehicle { }
extension Car {
override func run() { /* do another thing */ }
}
[B] Fonction de substitution des classes internes, qui est le descendant de NSObject
.
extension UIWindow {
// UIWindow is a descendant of NSObject, and its superclass UIView has this function then you can override
override open func becomeFirstResponder() -> Bool {
...
return super.becomeFirstResponder()
}
}