KVO가 구원자?

프로젝트는 아이폰의 기본 설정이 아닌 프로그램에서 언어를 즉시 설정해야 한다.현재의 프로젝트는 이미 비교적 번잡하고 때로는 보기가 직접 불러오기도 하고 때로는 네비게이션 표시줄을 사용하기도 하고 때로는ddSubView 등이 일일이 설명하지 못하며 각 보기마다 다른 입구가 있을 수 있기 때문에 어쨌든 관리하기가 매우 번거롭기 때문에 현재 보기가 어떻게 불러오는지 상관없이 언어를 바꾸는 통지를 받아야 한다.그럼요. 사실 알림을 할 필요도 없어요. 아이폰 프로그램의 특수성 때문에 어차피 한 번에 하나의 인터페이스를 표시할 수 있잖아요. 그럼view Will Appear 같은 함수에서 User Defaults 메커니즘을 통해 언어 값을 검사하면 돼요.그러나 비극적인 것은 현재 이 프로그램은 입구가 매우 많기 때문이다. 특히 내비게이션 표시줄은 윈도우의addSubView로 불러와 표시하는 것이 아니기 때문에 내비게이션 표시줄의 보기는 곧 표시되고 보기는 곧 사라질 것이다.그래서 현재 보기를 관리하고 싶지 않고 현재 보기를 동적으로 제어할 수 없습니다. 보기 제어 클래스를 썼습니다. 그 안에 생성된 모든 보기를 수용하는 그룹이 있습니다. 표시될 모든 보기의viewDidLoad나 initWithNibName에 그 그룹을 추가하고 언어가 바뀔 때 그룹의 모든 보기에 메시지를 보내서 언어를 바꾸도록 합니다.
 
이렇게 하면 적어도 언어의 동태를 바꿀 수 있을 뿐만 아니라 현재의 구체적인 어떤 보기든 상관없다. 그러나 어느 정도에 더 비극적인 점이 나타난다. 보기는 수조에 불러온다. 그러면retain에 의해 제거된다. 그러나 그 수조에서 제거하는 방법은 보기의 dealloc에 기록된다. 그럴 수 있을까?뷰를 동적으로 제거하시겠습니까?나는 보기 자체가 언제 불러오는지 관리하고 싶지 않다고 믿는다. 너는 보기가 언제 표시되지 않는지 어떻게 알 수 있겠니?언어를 바꿔야 할 모든 보기가 만들어지고 그 그룹에 추가되면 삭제될 가능성이 없습니다.
 
마침 어떤 동료가 나에게 KVO에 대해 이야기했다. 나는 이것이 코코아가 매우 중요하지만 이해하기 어려운 일환이라는 것을 기억한다. 몇 번 봤는데 이것이 정말 좋은 약이라는 것을 발견했다. 감청자의 유형에 신경 쓸 필요가 없다. 키값 변화자와 감청자는 실질적으로 연근을 풀고 감청자의 수를 임의로 늘릴 수 있다.이론적으로 KVO는 KVC를 이해해야 하는데 저도 사실 잘 몰라요. 먼저 응용을 보고 본질에 깊이 들어가세요.현재 가장 간단하면서도 정통적인 예가 하나 있다. 예를 들어 나는 정해지지 않은 보기가 있기 때문에 Language와 같은currentLanguage 속성을 주목해야 한다. KVO이론상 대상 간의 관계이지 클래스 간의 관계가 아니다. 너는 반드시 실체가 있어야 하고 실체의 속성을 바꿔야 한다. 그러면 이 속성이 바뀐 다른 실체를 주목하면 통지를 받을 수 있다.
@interface Language : NSObject {
 @private
    NSString *currentLanguage;
}

@property (nonatomic, copy)NSString *currentLanguage;
+ (id)sharedInstance;
@end

이것이 바로 우리가 주목해야 할 언어 관리이다. 반드시 대상 간의 관계이기 때문에 하나의 예를 사용했다. 그러면 우리가 해야 할 일은 두 가지이다. 첫째는 언어가 설정된 곳에서 이 속성을 바꾸는 것이다. 다른 하나는 이 변화를 감청해야 하는 곳에서 감청을 늘리는 것이다. 첫 번째는 말하지 않고 두 번째를 중시한다.xxxViewController가 이미 있다고 가정합니다
- (void)viewDidLoad
{
    [super viewDidLoad];
    [[Language sharedInstance] addObserver:self 
                                forKeyPath:@"currentLanguage" 
                                   options:NSKeyValueObservingOptionNew
                                   context:NULL];
}

물론 감청을 늘리면 당신이 필요로 하는 곳에 쓸 수 있다. 여기에addObserver 방법을 중시한다. 먼저 우리는 메시지의 수용자가 xxxViewController가 아니라 언어 관리 클래스의 실례를 볼 수 있다. 첫 번째 파라미터는 xxxxViewController이다. 의미적으로 말하자면 언어 관리 실례는 감청하고자 하는 속성이 바뀐 모든 실례를 추가한다.forKeyPath는 정통적인 용법이기 때문에 속성에 성명된 변수 이름을 쓰면 됩니다.옵션은 당신이 감청해야 할 유형을 선택하는 것입니다. 저는 새로운 값만 주목하도록 설정했습니다. |연결은 새로운 값과 낡은 값, 심지어 0으로 직접 작성할 수 있습니다. 그러면 속성 변화가 중요하지 않습니다.context는 별로 신경 쓰지 않았습니다. 아마도 사용자 감별용으로 쓰일 것입니다.
 
이 소식을 받아들이려면 프로토콜 함수를 실현해야 한다
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{    

}

분명히 이 예에서 첫 번째 값은 당신이 관심을 가지는'current Language'이고 두 번째 id는 언어 관리 클래스의 단례입니다. 이것은 당신이 하나의 속성 변화를 감청하여 구분할 수 있도록 하기 때문입니다.관건은change 매개 변수입니다. 실제 값은 당신이 감청하는 옵션을 설정한 것에 달려 있지만, 적어도 한 가지는 있을 것입니다. 두 번째 항목은 당신이 감청하는 내용입니다. 예를 들어 이 예에서 우리가 감청하는 유형은 NSKey Value Observing OptionNew입니다. 그러면change의 두 번째 키 값의 키는 @ "new"이고 값은 구체적인 새 값이 될 것입니다.
다른 모든 감청 실현도 비슷하다.어느 곳에서든 있기만 하면
[Language sharedInstance].currentLanguage = xxx;

이런 조작은 모든 감청이 통지를 받을 것이다.
마지막으로 감청 빼는 거 잊지 마세요.
- (void)dealloc
{
    [[Language sharedInstance] removeObserver:self forKeyPath:@"currentLanguage"];
    [super dealloc];
}

그리고 안심할 수 있는 것은 감청과 피감청자는 연근을 풀기 때문에 감청을 늘릴 때 인용계수를 늘리지 않기 때문에 dealloc는 감청을 제거하는 데 전혀 문제가 없고 논리에 부합된다.
 
특히, 상례의 정통적인 용법, 즉 관심 대상의 속성 값이 바뀌고, 만약 당신이 속성 이름을 잘못 쓰면 프로그램은core가 떨어진다.사실 속성 값의 변화를 전혀 감청하지 않고 단지 어떤 소식을 감청할 수 있다. 이것은 NSNotification과 약간 비슷하고 번거로울 수도 있다. 물론 메커니즘적으로 완전히 다르다. 예를 들어 메시지 발송 센터의 개념이 전혀 없다.겸사겸사 말씀드리겠습니다.
우선 그것들은 실례와 실례의 관계이고, 그 다음에 forKeyPath는 메시지를 구분하는 데 사용할 문자열을 마음대로 쓸 수 있다.속성이 없으면 새 값과 낡은 값도 존재하지 않기 때문에 옵션은 0을 직접 쓰면 됩니다.동시에 감청자는 바꿀 만한 것이 없지만 발송자는 약간 다르다. 감청 속성이 아닌 이상 속성이 아무리 바뀌어도 알림을 촉발할 수 없기 때문에 반드시 수동으로 촉발해야 한다. 예를 들어 이렇게
[[Language sharedInstance] willChangeValueForKey:@"NonProperty"];
// to change someting
[[Language sharedInstance] didChangeValueForKey:@"NonProperty"];

그러면 [Language shared Instance]에 등록된 @ "NonProperty"메시지의 감청자는 모두 이 알림을 받을 것입니다. 물론 이 알림이 무슨 소용이 있는지는 응용에 달려 있습니다.근데 아무도 안 그랬겠지.
 
자세한 내용은 공식 문서를 참조하십시오Key-Value Observing Programming Guide.
 
지금까지 생각해보면 이렇게 짜증날 필요가 없잖아. 정보센터에 직접 등록하면 되잖아. 수조에 써도 보기 컨트롤을 입력하지 않고 보기 컨트롤에 소포를 한 겹 넣고 소포류를 조작하면 되잖아. 왜 KVO를 해? 그리고 그 원리를 잘 몰라.

좋은 웹페이지 즐겨찾기