父类和子类之间的弱引用

时间:2017-01-22 01:30:16

标签: ios swift memory-management

我们可以像下面的代码那样在类之间进行通信,而不是使用委托/协议模式和通知。我还没有看到像这样的代码示例。但只是好奇地知道为什么这应该起作用。

class Class1 {

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

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

class Class2 {

   weak var class1Obj: Class1?

   func class2Method() {
      class1Obj.class1Method()
   }

}

1 个答案:

答案 0 :(得分:3)

你在这里委托模式。您的委托属性仅称为class1Obj,而不是更常见的delegate名称。这里的关键问题是你没有使用协议,因此这两个类是“紧密耦合的”,即Class2高度依赖于Class1实现的细节。此外,通过这两个紧密耦合的类,不能立即明确Class1 Class2可能需要哪些方法。它使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没有依赖关系),就像在...中使用协议一样委托模式做了。但希望上面的闭包示例说明了丰富的委托协议模式的简单替代方法。