2017-05-17 1 views
0

순수한 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" 

, 나는 같은 방법으로 Person 객체의 변경 사항에 귀를 기울 UIViewController 있었다 대신 HouseHold의 말할 수 있습니다. 메모리 누출이 있습니까?

또한 패턴에 대한 의견을 환영합니다. 나는 제네릭을 사용하고 싶기 때문에 내가 관찰하고 싶은 각각의 특성에 대해 기능을 만들 필요가 없다. 또는 현재 코드처럼 전체 객체를 전달하십시오.

참고 : 놀이터에서 컴파일

주 2 : reactive cocoa를 사용하지 않고 더 MVVM 아키텍처로 이동하려고합니다.

+0

가있다 :

HouseHold has Person, Person has HouseHold. 

당신은 deinit 방법을 확인하여 누수를 테스트 할 수있는 코드가 변경되었을 경우

사이클 의지가 발생합니다 강력한 참조주기는 없지만 항상 클로저를 사용하는 것이므로'w를 사용하도록주의해야합니다. eak' 또는'unowned' 캡처리스트를'listen' 클로저에 넣습니다. 더 넓은 아이디어에서, 나는 당신이하려고하는 것을 얻는다. 그러나 모든 속성에 대해'didSet' 옵저버로 모델 타입을 쓰다듬어 야하는 것은 다소 관대하다. KVO 기반 접근 방식이 덜 관입적 (그리고보다 유연하게)할지 궁금합니다. – Rob

답변

2

코드에 보존주기가 없습니다. 원인 :

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

위의주기가 없습니다.

person.listen = self 

상황입니다 :

class Person { 

    //... 

    deinit { 
     print("Person deinited") 
    } 
} 

class HouseHold { 

    //... 

    deinit { 
     print("HouseHold deinited") 
    } 
}