현재 iOS 용 양식 컨트롤러를 다시 쓰고 있습니다. 그것은 모델에 바인딩 된 사용자 지정 개체이며, 양식 필드 편집, 이전/다음 필드로 이동, 사용자 지정 키보드 처리, 데이터 유효성 검사 등을 처리합니다.양방향 KVO : 컨트롤러 업데이트 모델
첫 번째 버전은 양식을 저장하기위한 plist 값이 있으면 폼 컨트롤러는 모든 데이터 자체를 보유합니다. 이제 저장소 (모델)와 양식 컨트롤러를 분리하려고합니다. 따라서 KVO를 사용하여 정착했습니다.
간단히 말하면 부재중 시간대를 편집하도록 설계된 양식이 있다고 가정 해 보겠습니다. 따라서 두 개의 필드가 있습니다 : leaveDate
및 returnDate
. 다음과 같이
내 모델은 다음과 같습니다
@interface Absence
@property (strong, nonatomic) NSDate *leaveDate;
@property (strong, nonatomic) NSDate *returnDate;
@property (readonly, nonatomic) BOOL isValid;
@end
내 폼 컨트롤러는이 객체를 가리키는 속성 model
있습니다.
사용자가 내 XIB의 "leave date"텍스트 필드를 누르면 Form Controller는 내 모델의 leaveDate
의 현재 값을 기반으로 날짜 선택 도구를 입력하고 표시합니다. 사용자가 다른 날짜를 선택하면 양식 컨트롤러가 setValue:forKey:
을 사용하여 모델을 업데이트합니다.
isValid
속성 (+keyPathsForValuesAffectingIsValid
사용) leaveDate
및 returnDate
영향 것으로 선언되고, 폼 컨트롤러는 즉시 제출 버튼을 활성화/비활성화,이 속성의 변화를 시청 등록했습니다.
지금까지 모든 것이 매력처럼 작동합니다. 이제 꼬인 부분 :
열려있는 동안 내 양식 컨트롤러가 모델의 변경 사항을 처리 할 수있게하려고합니다. 예 : 모델에 "지난 3 일 이상 부재 중이어야합니다"라는 규칙이 있습니다. 사용자가 휴가 날짜를 변경하면 총 기간이 3 일을 초과하지 않으면 반환 날짜가 자동으로 조정됩니다.
그래서 내 양식 컨트롤러는 모든 속성의 변경 사항을 수신하기 위해 등록해야합니다. 문제는 속성을 변경하고 변경 내용을 수신한다는 것입니다.
그런 식으로 사용자가 leaveTime
을 변경할 때 양식 컨트롤러는 setValue:forKey:
을 사용하여 모델을 업데이트하지만 방금 한 바로 그 변경 사항에 대한 KVO 알림을 즉시받습니다. 이것은 불필요하고 잠재적으로 해롭다 (나는 방금 나 자신에게 변화를 가져왔다, 나는 방금 그것을했다는 말을들을 필요가 없다).
[self.model removeObserver:self forKeyPath:self.currentField.key];
[self.model setValue:newValue forKey:self.currentField.key];
[self.model addObserver:self forKeyPath:self.currentField.key options:NSKeyValueObservingOptionNew context:nil];
그것은 작동하고
을하지만 추한 및 성능 - :
유일한 방법의 주위에 지금 바로 새 값을 설정하기 전에 다음과 같이 직후 등록 재 등록 해제 될 때까지 발견 현명한 나는 그게 좋다고 생각하지 않는다.
더 나은 방법에 대한 설명이 있습니까?
TL; DR
ControllerA
는 Model
의 등록 KVO 옵저버이다.
ControllerB
업데이트 Model
==>ControllerA
은 KVO 알림을받습니다. 괜찮아.
ControllerA
업데이트 Model
==>ControllerA
은 KVO 알림을받습니다. 나는 이것을 원하지 않는다.
방금 전에 변경 한 KVO 알림을 듣는 것에 대해 위험한 것은 무엇입니까? 나는 그 옵션이 KVO 관측자로서 자신을 제거한 다음 다시 추가하는 것보다 덜 복잡하고 잠재적으로 해롭다 고 생각합니다. – occulus
모델을 업데이트하기 전에 마지막으로 수행 한 작업이'textField.text = @ "something";'일 때'textField.text = @ "something"; "을 실행하고 싶지 않습니다. 그것이 자주 발생하는 더 값 비싼 UI 업데이트 (큰 컨트롤의 다시 그리기, 이미지 처리 ...) (슬라이더와 같은 개별 컨트롤)를 상상해보십시오. – Cyrille
알림을받는 것이 멱등 한 작업임을 확신 할 수 있으면 동일한 알림을 여러 번받는 것이 중요하지 않아야합니다. – occulus