保留周期Swift闭合

时间:2017-05-17 07:44:25

标签: ios swift generics mvvm key-value-observing

我正在考虑使用这种模式(或接近它的模式)来观察纯Swift对象的变化。

此代码是否有内存泄漏?

class Person {

   var name: String {
       didSet{
           self.listen?(self)
       }
   }

   var phone: Int {
       didSet{
           self.listen?(self)
       }
   }

   var listen: ((_ person: Person) -> Void)?

   init(withName N: String, andPhone P: Int) {
       self.name = N
       self.phone = P
   }
}

 class HouseHold {

   var people = [Person]()

   let changes: (_ person: Person) -> Void = { person in
       print(person.name)
   }

   init(withPeople P: [Person]){
       self.people = P
       for person in people {
           person.listen = self.changes
       }
   }
}

let jon = Person(withName: "Jon", andPhone: 1232344567)


let thais = Person(withName: "Thais", andPhone: 1232344567)


let apartment = HouseHold(withPeople: [jon, thais])

jon.phone = 1232399999
jon.name = "Jon Smith"
jon.phone = 9999999999
thais.name = "Thais Smith"

另外,我要说的是HouseHold而不是UIViewController,而是Person以同样的方式收听lazy对象的更改。会有内存泄漏吗?

此外,欢迎对该模式发表评论。我很想使用泛型,所以我不必为我想要观察的每个属性创建一个函数。或者像目前的代码那样传递整个对象。

注意:在游乐场编译<​​/ p>

注2:尝试在不使用reactive cocoa的情况下转向更多MVVM架构。

1 个答案:

答案 0 :(得分:2)

您的代码没有保留周期。因为:

HouseHold has Person, HouseHold has changes, Person has HouseHold.changes. 

上面没有循环。

如果您的代码更改为:

,则会发生循环
person.listen = self

情况是:

HouseHold has Person, Person has HouseHold. 

您可以通过检查deinit方法来测试泄漏:

class Person {

    //...

    deinit {
        print("Person deinited")
    }
}

class HouseHold {

    //...

    deinit {
        print("HouseHold deinited")
    }
}