Langue: Swift 3Comment appeler une fonction en option à l'aide de sélection et NotificationCenter
IDE: XCode 8.3.2 (8E2002)
J'ai un protocole avec une fonction optionnelle foo
@objc protocol SomeProtocol {
@objc optional func foo(_ notification: Notification)
}
extension SomeProtocol {
func listenToFoo() {
NotificationCenter.default.addObserver(self, selector: #selector(self.foo(_:)), name: NSNotification.Name(rawValue: "UltimateNotificationKeyLOL"), object: nil)
}
}
Si j'étire ce code à classe, par exemple UIViewController
.
class CrashingViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.listenToFoo()
}
}
extension CrashingViewController: SomeProtocol { }
Maintenant vient ici le problème, étant donné que foo
est une fonction optionnelle, si quelqu'un envoie un Notification
la NSNotification.Name(rawValue: "UltimateNotificationKeyLOL")
touche l'application se bloque parce que je ne l'ai pas encore mis en œuvre foo
. Donc dans ce cas, le code ci-dessus provoquera un crash.
Cependant, si je fais ce
class GodzillaViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.listenToFoo()
}
}
extension GodzillaViewController: SomeProtocol {
func foo(_ notification: Notification) {
print("lol")
}
}
Aucun accident est créé depuis foo(_:)
est pas une option plus.
également: Ce code ne peut #selector(self.foo?(_:))
Question: Est-il possible d'avoir un sélecteur appeler une fonction facultative sans écraser l'application?
@Hamish est correct, vous ne pouvez pas utiliser NotificationCenter pour les fonctions qui ne sont pas exposées à Obj-C –
@Hamish Vous avez raison, je mis à jour la réponse pour utiliser une autre fonction 'addObserver' qui ne nécessite pas @objc! Merci – Thomas
@ZonilyJame La méthode '# selector' est ce qui nécessite l'exposition d'une méthode à ObjC. Il y a bien sûr d'autres possibilités comme celle que je change, ou si vous voulez vraiment utiliser des sélecteurs pour une raison quelconque, vous devriez regarder la variante Swift qui fonctionne quelque chose comme ça à la place 'Selector (" foo (_ :) ")' – Thomas