2012-01-19 4 views
1

개별 모델 객체에 대한 속성 변경에 관심이있는 모델 객체 및 컨트롤러 객체의 목록이 있다고 가정 해보십시오. 객체를 추가 할 때 컨트롤러와 모델 객체간에 KVO를 사용하고자하는 각 키에 대해 addObserver를 사용합니다. 이제 관찰 된 객체 중 하나가 사라지면 특정 키에 대한이 개별 객체의 변경 사항을 관찰하지 않도록 View Controller에 알려야합니다.개별 관측 된 키의 KVO 정리

우아한 방법은 무엇입니까? 내가 생각할 수있는 가장 좋은 방법은 내 컨트롤러에서 addObserver라고 부르는 새 키 kRemoveObject를 추가하는 것입니다.이 키는 객체가 삭제되기 전에 트리거됩니다. 그런 다음 특정 인스턴스에 대한 kRemoveObject를 포함하여 모든 관찰 된 키를 제거합니다. 누구든지 더 깨끗한 방법을 알고 있습니까? 이것은 약간 성가시다.

컨트롤러에 대한 참조를 얻기 위해 관찰 된 객체를 사용 : 내 머리 위로 떨어져

답변

0

나는이 매우 우아한 방법을 발견했으며, KVO가 observeValueForKeyPath로 추가하는 커다란 "switch 문"인 KVO에 관해 항상 나를 괴롭혔던 것들 중 하나를 해결합니다.KVO + Blocks는 매우 멋지다. "switch statement"를 제거하고 자동으로 observer 제거를 처리하므로 ARC를 사용할 때 removeObserver를 호출 할 필요가 없다. (자신의 메모리 관리를한다면 removeObserverWithBlockToken을 호출해야한다고 생각한다. 나는 그것을 시도하지 않았다). 여기

http://blog.andymatuschak.org/post/156229939/kvo-blocks-block-callbacks-for-cocoa-observers

코드 : 당신이 당신의 블록에 자신을 참조하는 경우 https://gist.github.com/153676

한 가지는, 조심해야하지만, 일반적으로 블록의 진실하다 할 수있다. 다음을 수행해야합니다.

__block blockSelf = self; 

보유주기가 끝나지 않으면이 작업을 수행해야합니다. 자세한 내용은 Retain cycle on `self` with blocks을 참조하십시오.

다른 하나는 파일에 -fno-objc-arc를 입력하면 ARC와 함께 작동합니다. (자세한 내용은 How can I disable ARC for a single file in a project?을 참조하십시오.)

저는 Apple이 SDK에 이와 같은 것을 추가하기를 바랍니다.

+0

__block은 유지주기를 중단하지 않습니다. __weak을 사용해야합니다 – user1687195

+0

KVO는 큰 switch 문을 사용하도록 강요하지 않습니다. 그렇게하는 경우 구현을 재검토하고 싶을 수 있습니다. – quellish

0

. observer-object가 removeObserver : forKeyPath : 함수를 호출하게하십시오. 컨트롤러는 keyPath 목록을 제공해야합니다.

(EDIT : 이것을 수행하는 매우 깨끗한 방법은 관찰 된 개체에 대한 대리자 프로토콜 ("imDying"메서드 사용)을 정의하고 관찰 된 개체에 대리인 속성을 추가하고 컨트롤러를 대리인으로 설정하는 것입니다. 그리고 갖는 관찰 객체는 할당 해제에 대리인의 "imDying"메소드를 호출 더 나은 이름으로 "imDying"를 교체, ㅎ)

또는를 :..

는 컨트롤러가 observed-의 수명을 관리 되세요 객체로, 관찰 된 객체 dealloc보다 먼저 자신을 제거 할 수 있습니다.

+0

제안을 주셔서 감사합니다. 위임 접근 방식의 문제점은 KVO와 다른 메커니즘을 사용하고 있으며이를 관찰하고자하는 모든 개체가 해당 프로토콜을 채택해야한다는 것입니다. 두 번째 제안의 경우, 모델의 작업은 객체의 수명을 관리하는 것입니다. 모델 만이 실제로 사라질 때 컨트롤러가 모델의 변화에 ​​이끌 리도록해야합니다. – possen

+0

- NSNotificationCenter에 대한 언급을 삭제했습니다. 이는 KVO에서 사용하지 않았기 때문입니다. – MechEthan

+0

내가 KVO 기술로 이것을 할 수있는 방법이 있어야하는 것처럼 보입니다. 그래서 내가 설명한 해결책 만이 그것을 할 수있는 유일한 방법입니다. – possen

0

KVO를 사용하면 관찰자는 관찰하는 내용을 참고해야합니다. 만약 그렇다면, 관찰자가 참조를 너무 가지고 있기 때문에, 객체는 결코 사라지지 않을 것입니다.

관찰을 중지하려면 관찰자에게 확인하십시오.

하나의 값이 변경되기를 기다리는 경우 알림을 받으면 옵저버를 제거하십시오. (이미 제거 된 경우 관찰자를 제거하지 않도록주의하십시오.)

관찰자를 dealloc하면 정리할 것입니다 - 개체에 대한 나머지 모든 관찰을 제거하십시오.

관측자가 관찰 한 개체의 배열을 유지 관리하는 경우 일 수 있습니다. 사용 된 것을 보았지만 마음에 들지 않으며 매우 유연하지 않습니다.

내가 좋아하는 것은 KVOHelper라는 클래스입니다. 관찰 클래스에서 이것을 생성하고 관찰중인 객체, 관찰자 ​​및 키 경로를 전달합니다. 그것은 KVO를 둘러싼 포장지입니다. 원하는 경우 관찰자를 제거 할 수 있습니다. 또는 KVOHelper를 릴리스하면 dealloc 루틴에서 모든 것을 릴리스하기 전에 관찰자를 제거합니다. 동일한 관찰자를 여러 번 제거 할 수 없습니다 (예외가 발생 함). 또한 여러 KVOHelpers를 관리하기위한 KVOHelperSet과 함께 번들로 제공됩니다. 나는이 수업을 쓰기 위해 학점을받을 수 없다. 나는 프로젝트에서 일했던 한 남자에게서 그것을 얻었다. 하지만 지금은 항상 사용하고 있습니다. 원칙은 간단하고 자신 만의 것을 만들 수 있어야합니다.