2017-03-26 1 views
1

Mein Objekt:Wie in ClassB zu beobachten, wenn ein Objekt in ClassA erstellt wird?

//Object to observe 
struct Text { 
    let savedUserHeader: String 
    let savedUserText: String 
} 

ClassA, wo ich das Objekt erstellen:

//First Class 
class A { 
    func somefunc(){ 
     let a = Text(savedUserHeader: "testHeader", savedUserText: "testText") 
    } 
} 

In classB, möchte ich, wenn ein neues Objekt beobachten erstellt wurde:

//Second Class 
class B { 
    var text: Text? { 
     didSet{ 
     headerlabel.text = text.savedUserHeader 
     saveUserLabel.text = text?.savedUserText 
     } 
    } 
} 
+0

'a' ist wirklich ein variabler lokaler t o 'somefunc()'? –

+0

Sie sollten Ihre Architektur überdenken, wenn Sie auf diese Weise dem Benutzer Text anzeigen. Sie würden höchstwahrscheinlich explizit etwas in Code schreiben wollen wie 'instanceOfB.text = instanceOfText' und tun, was Sie bereits in' didSet' machen. Wenn Sie auf Momente warten, in denen Instanzen von "Text" erstellt werden, werden Sie fast keine Ahnung haben, woher Ihre Benutzeroberflächenfehler kommen werden, besonders wenn "Text" -Instanzen aus mehreren Threads und gleichzeitig erstellt werden können. Indem ich es explizit schreibe, wie ich es vorschlage, können Sie einen Haltepunkt darauf setzen und nur die Stapelverfolgung des Hauptthreads durchsuchen. –

Antwort

1

Delegierter

Sie können die Delegierten Muster verwenden, um zu beobachten, lassen Sie ein Protokoll ADelegate genannt erstellen:

protocol ADelegate { 
    func didCreateText(text: Text) 
} 

Dann eine Variable hinzuzufügen delegate in der Klasse A genannt und ein Text Objekt in didCreateText(text:) Methode im somefunc() passieren:

//First Class 
class A { 

    var delegate: ADelegate? 

    func somefunc(){ 
     let a = Text(savedUserHeader: "testHeader", savedUserText: "testText") 
     delegate?.didCreateText(text: a) 
    } 
} 

als nächstes, wenn Sie ein Objekt A in B erstellen, setzen a.delegate = self und ADelegate Protokoll implementieren:

//Second Class 
class B: ADelegate { 

    var headerlabel: UILabel! 
    var saveUserLabel: UILabel! 

    var a = A() 

    var text: Text? { 
     didSet{ 
      headerlabel.text = text?.savedUserHeader 
      saveUserLabel.text = text?.savedUserText 
     } 
    } 

    init() { 
     a.delegate = self 
    } 

    func didCreateText(text: Text) { 
     print("savedUserHeader: \(text.savedUserHeader)") 
     print("savedUserText: \(text.savedUserText)") 
    } 
} 

Das war's! Das Verfahren didCreateText(text:) aufgerufen wird, wenn ein Objekt Text im somefunc() Methode erstellt:

let b = B() 
b.a.somefunc() 

Notification Center

Eine andere Lösung ist NotificationCenter. Lassen Sie eine Benachrichtigung hinterlassen, wenn ein Text Objekt erstellen:

func somefunc(){ 
    let a = Text(savedUserHeader: "testHeader", savedUserText: "testText") 
    NotificationCenter.default.post(name: Notification.Name("addText"), object: a) 
} 

und beobachten in der Klasse B:

init() { 
    NotificationCenter.default.addObserver(self, selector: #selector(observeText(noti:)), name: Notification.Name("addText"), object: nil) 
} 

@objc func observeText(noti: Notification) { 
    if let text = noti.object as? Text { 
     print("savedUserHeader: \(text.savedUserHeader)") 
     print("savedUserText: \(text.savedUserText)") 
    } 
} 

Let Test it:

let b = B() 
let a = A() 
a.somefunc() 

Sie das Ergebnis sehen:

savedUserHeader: testHeader 
savedUserText: testText 
+0

Obwohl dies eine Lösung sein könnte, glaube ich, dass Delegieren für einen solchen Fall nicht die beste Wahl ist. –

+0

Was ist mit Benachrichtigungslösung? –

+0

@DanhHuynh Ich versuchte beide und beide arbeiteten, vielen Dank. Der mit Benachrichtigungen schien natürlicher, weil derjenige mit dem Protokoll diesen unbekannten "b.a.somefunc" -Aufruf hatte. Interessant wäre es zu wissen, welcher Weg sicherer ist oder der bevorzugte Weg zum Beobachten.Danke nochmal, hat mir sehr geholfen :) – imrano10

Verwandte Themen