2015-11-23 15 views
14

Si consideri il seguente:Osservatore di proprietà Swift nell'estensione del protocollo?

protocol ViewControllable: class { 
    typealias VM: ViewModellable 
    var vm: VM! { get } 
    func bind() 
} 

extension ViewControllable { 
    var vm: VM! { 
    didSet { 
     bind() 
    } 
    } 
} 

sto cercando di osservare vm proprietà e chiamare bind ogni volta che viene iniettato. Ma questo non compila con detto errore:

estensioni non possono contenere proprietà memorizzate

che ha senso dal momento che il protocollo non può far rispettare le proprietà di essere stored o computed.

È possibile eseguire questa operazione senza introdurre class inheritance?

In altre parole, È possibile osservare la modifica di una proprietà all'interno dell'estensione del protocollo?

+0

nota che è possibile farlo facilmente, * se si utilizza una proprietà associata *. Ecco un post recente su di me su come creare una proprietà associata: [esempio] (http://stackoverflow.com/documentation/swift/1085/associated-objects/27656/property-in-a-protocol-extension-achieved -using-associated-object # t = 20170128181236289743) Questo è abbastanza fresco mentre scrivo questo, quindi spero che sia abbastanza stabile. – Fattie

+0

Per quanto riguarda questa domanda, un esempio perfetto di dove si potrebbe usare questo è l'esempio utilizzato in questo QA: http://stackoverflow.com/questions/41910120/in-swift3-combine-respondsto-and-calling-in-one- fell-swoop – Fattie

risposta

24

No, questo è esplicitamente disabilitato. Vedere Extension: Computed Properties:

Le estensioni possono aggiungere nuove proprietà calcolate, ma non possono aggiungere proprietà archiviate o aggiungere osservatori di proprietà a proprietà esistenti.

Tenere presente che se ciò fosse legale, aggiungerebbe una confusione non banale sull'ordine di esecuzione. Immagina che ci siano diverse estensioni che hanno aggiunto didSet e che l'implementazione effettiva abbia anche un didSet. In quale ordine dovrebbero correre? Questo non significa che sia impossibile da implementare, ma potrebbe essere un po 'sorprendente se ce l'avessimo.

+2

Grazie per il chiarimento. Ma mi permetto di non essere d'accordo sulla ** confusione ** che potrebbe portare con sé. Molti altri linguaggi di programmazione trattano questo tipo di problema dei diamanti rendendoli espliciti con errori di compilazione o inferendo dall'ordine delle dichiarazioni. Scala, per esempio, quando è in conflitto, dà la priorità a qualsiasi 'trait' (' protocol') che viene dichiarato dopo in classe 'extends' (': '). –

+0

> "In quale ordine devono essere eseguiti?" davvero? Naturalmente volevo avere questa funzionalità. Es. Hai un nuovo cliente. L'unica informazione che ti interessa è il suo identificatore univoco. Si imposta l'identificatore. All'inizio dell'impostazione di questo identificatore, i metodi del protocollo vanno a prendere tutte le informazioni sul cliente di cui abbiamo bisogno. Non è difficile eseguire il codice nell'ordine corretto Desidero che il codice si occupi di tutto il resto, senza doversi preoccupare di chiamare manualmente tutte le funzioni. Come ora, è scomodo lavorare con i protocolli e le estensioni senza questa heartache – Ferologics

+0

uuuh :( –

Problemi correlati