J'ai vraiment aimé la réponse de Sulthan (Anonymous class in swift) qui décrit la construction d'un objet conforme à un protocole mais dont la classe est cachée dans une fermeture. Cependant, lorsque j'essaie de faire quelque chose d'utile avec ça, j'échoue parce que la fermeture ne se ferme pas sur l'extérieur. les membres de l'instance de la classe à l'intérieur de la classe interne.Pourquoi les fermetures ne peuvent-elles pas se refermer sur les membres de l'instance
protocol EventListener {
func handleEvent(event: Int) ->()
}
class Recorder {
static var events = [Int]() // static is forced
var listener: EventListener = {
class R : EventListener {
func handleEvent(event: Int) {
events.append(event)
print("Recorded: \(event)")
}
}//
return R()
}()
}// Recorder
class Distributor {
var listeners = [EventListener]()
func register(listener: EventListener){
listeners.append(listener)
}
func distribute(event: Int){
for listener in listeners {
listener.handleEvent(event)
}
}
}
var d = Distributor()
var r1 = Recorder()
var r2 = Recorder()
d.register(r1.listener)
d.register(r2.listener)
d.distribute(10)
print(Recorder.events) // [10, 10] Same event recorded twice.
Ce qui précède compile et s'exécute. Mais je veux events
dans Recorder
pour être un membre d'instance afin que chaque enregistreur ait son propre enregistrement. La suppression de static
renvoie l'erreur du compilateur: le membre d'instance 'events' ne peut pas être utilisé.
J'ai essayé de définir une instance func record(event)
dans Recorder pour handleEvent(event)
pour appeler, mais j'obtiens la même erreur.
La réponse de Marius (en Instance member cannot be used on type | Closures) suggère que vous ne pouvez pas accéder aux membres d'instance pendant que les propriétés sont en cours de définition, donc j'ai aussi essayé de calculer l'écouteur plus tard comme ça.
class Recorder {
var events = [Int]()
var listener: EventListener {
class R : EventListener {
func handleEvent(event: Int) {
events.append(event) // error: can't access events
print("Recorded: \(event)")
}
}
return R()
}
}// Recorder
Mais le compilateur dit qu'il ne peut pas accéder au l'auto externe.
Les fermetures semblent assez impuissantes si elles ne peuvent pas accéder aux selfs externes. En Java, vous pouvez obtenir des selfs externes avec quelque chose comme Recorder.self.events
. Et Recorder.self.
ne sera peut-être nécessaire que s'il y a des conflits de noms (?)
Est-ce que Swift est conçu de cette façon ou qu'est-ce qui me manque?
Comment l'écririez-vous donc Recorder
donne Distributor
un objet qui ne peut rien faire mais recevoir des messages handleEvent?
Merci beaucoup.
Merci de votre visite! Laisse-moi jouer avec ça un moment. – adazacom