2017-01-22 22 views
1

我們可以像下面的代碼那樣在類之間進行通信,而不是使用委託/協議模式和通知。我還沒有看到任何這樣的代碼示例。但只是想知道爲什麼這應該工作或不工作。父類與子類之間的弱引用

class Class1 { 

    var class2Obj: Class2 = Class2() 
    init() { 
     class2Obj.class1Obj = self 
    } 

    func class1Method() { 
     print("Parent") 
    } 
} 

class Class2 { 

    weak var class1Obj: Class1? 

    func class2Method() { 
     class1Obj.class1Method() 
    } 

} 
+0

是的,你可以這樣溝通。但是對於其他人來說,代理,阻止和關閉更容易理解Class2通過「方法」回調。這是一個「什麼是最佳實踐」的問題:) –

+0

@YUNCHEN - 是的,你也可以使用閉包模式,但我認爲使用閉包是最好的做法。 ,它比這更復雜,它的確依賴於在簡單的情況下,閉包可能是有用的,但是在更豐富的接口中,委託協議模式通常是優越的,它只取決於接口的性質,但是我同意,安舒的兩個緊密耦合的班級模式並不理想。 – Rob

+0

@Rob,同意你的看法。 –

回答

3

你這裏什麼委託模式。您的代理人財產僅僅被稱爲class1Obj,而不是更習慣的delegate名稱。這裏的關鍵問題是你沒有使用協議,結果這兩個類是「緊密耦合」的,即Class2高度依賴於實現的細節。此外,對於這兩個緊密耦合的類,目前還不清楚Class2可能需要哪些方法Class1。這使得維護Class1更難,因爲很容易意外地做出改變,打破Class2中的行爲。這也使得難以使用Class2Class1以外的其他類別結合使用。

相反,您通常會聲明一個協議來精確地闡述Class2與其他可能需要使用它的對象之間的契約性質。結果是這些類不太緊密耦合,即Class2除了符合所討論的協議外,不需要了解其他類。此外,在編輯Class1時,如果您聲明它符合協議,編譯器會在您未能實現某些必需的方法或屬性時發出警告。

因此,預先工作量可以忽略不計,協議使代碼更容易維護。它還提供了一些額外的靈活性,您可以在將來使用Class2Class1以外的其他內容結合使用。

底線,協議可以導致代碼更容易維護,更靈活,沒有隱藏的假設。


如果你不想使用委託協議模式,另一種選擇是使用閉包,其中Class1提供的代碼,Class2可以調用的模塊。所以,你可以這樣做:

class Class1 { 

    var class2Obj = Class2() 

    init() { 
     class2Obj.handler = { [weak self] in  // note `weak` reference which avoids strong reference cycle 
      self?.class1Method() 
     } 
    } 

    func class1Method() { 
     print("Parent") 
    } 
} 

class Class2 { 

    var handler: (() -> Void)? 

    func class2Method() { 
     handler?() 
    } 

} 

而當你有兩個類之間的豐富的接口,這種封閉模式,當你有兩個類之間的接口非常簡單的委託協議模式是有益的。

坦率地說,上述更常見的置換是關閉與Class1Class2中啓動的某個特定請求更直接相關的地方。因此,您可以將參數設置爲Class2中的適當方法。此外,你經常將數據傳遞回來,所以可想而知,我們傳遞迴一個可選String

class Class1 { 

    var class2Obj = Class2() 

    func performClass2Method() { 
     class2Obj.class2Method { string in 
      guard let string = string else { return } 

      self.class1Method() 
     } 
    } 

    func class1Method() { 
     print("Parent") 
    } 
} 

class Class2 { 

    func class2Method(completionHandler: @escaping (String?) -> Void) { 
     // do something which creates `string` 

     // when done, call the closure, passing that `string` value back 

     completionHandler(string) 
    } 

} 

這些閉合模型一個偉大的方式做對象之間的簡單接口外,還保持了兩類非常鬆散耦合(即Class2Class1沒有依賴關係),就像在委託模式中使用協議一樣。但希望上面的關閉示例說明豐富的委託協議模式的簡單替代方案。