본문 바로가기
프로그래밍 놀이터/iOS

[Objective-C] 키-값 코딩

by 돼지왕 왕돼지 2018. 1. 11.
반응형

 [Objective-C] 키-값 코딩


출처 : OS X 구조를 이해하면서 배우는 Objective-C Chap 20.

., @private, @public, accessInstanceVariablesDirectly, addObserver, Applescript, Cocoa 바인딩, compliance, countOf____, Dot, get____, id 형, indexed accessor pattern, insertObject, insertObject:inNamesAtIndex, ioValue, key path, key value coding, key value observer, key-value coding, key-value observing, KVC, KVC 준수, kvo, mutableArrayValueForKey, mutableArrayValueForKeyPath, mutableSetForkey, NSArray, NSDictionary, NSInvalidArgumentException, NSKeyValueChangeIndexesKey, NSKeyValueChangeInsertion, NSKeyValueChangeKindKey, NSKeyValueChangeNewKey, NSKeyValueChangeOldKey, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement, NSKeyValueCoding, NSKeyValueObservingOptionNew, NSKeyValueObservingOptionOld, NSMutableArray, nsmutabledictionary, NSNotification, NSNumber, NSPoint, NSRange, NSRect, NSSize, NSUndefinedKeyException, NSValue, objectIn____AtIndex, observeValueForKeyPath, outError, removeObjectFromNamesAtIndex, removeObjectFrom____AtIndex, removeobserver, replaceObjectIn____AtIndex, setKeys, setNilValueForKey, setValue, setValue:forKey, setValue:forKeyPath, setValue:forUndefinedKey, to-many relationship, to-one relationship, triggerChangeNotificationsForDependentKey, underbar, validateName:error, validateValue, validate____, valueForKey, valueForKeyPath, valueForUndefinedKey, [Objective-C] 키-값 코딩, _, 객체, 관찰자, 구조체, 다대다 관계에 변경 가능한 접근, 다대다 관계의 접근, 다대일 관계와 다대다 관계, 대리 객체, 도트, 래핑, 리시버, 밑줄로 시작하는 이름은 메서드, 배열 객체와 키-값 코딩, 사전 객체와 키-값 코딩, 속성값의 자동 변환, 스칼라값, 인덱스가 있는 접근자 패턴, 인스턴스 변수명, 접근자 메서드로 변경, 키-값 감시, 키-값 코딩, 키-값 코딩 준수, 키-값 코딩에 준수한 방법으로 접근자 또는 인스턴스 변수에 접근할 때, 키패스, 키패쓰, 타깃-액션 패러다임의 약점, 프로퍼티 값 검증, 프로퍼티에 접근, 프록시 객체


20.1. 키-값 코딩 개요


* 20.1.1. 키-값 코딩이란


-

변수접근 방법 중, @public 으로 해서 인스턴스 변수에 접근시키는 방법도 있으나, 그다지 추천하는 방법은 아니다.



-

키-값 코딩(key-value coding)은 객체가 지닌 정보를 나타내는 문자열을 키로 사용해서 간접적으로 그 정보에 접근하는 구조이다.

기본적으로 접근자 메서드가 선언 프로퍼티 또는 인스턴스 변수라면 그 이름을 문자열로 지정해서 접근할 수 있는 매우 강력한 기능이다



-

키-값 코딩의 접근이 간접적이라는 것은 다음 두 가지 이유에서다.


1. 키가 되는 문자열은 실행 중에 결정해도 된다.

2. 프로퍼티에 실제 접근하는 방법은 사용하는 쪽에서는 보이지 않는다.



-

GUI 작성이나 변경이 용이하도록 도입된 기술인 Cocoa 바인딩이나 AppleScript 에서 조작 가능한 앱 개발에서도 키-값 코딩은 중요한 요소로 사용된다.



-

키-값 코딩, 키-값 감시는 iOS 에서도 이용할 수 있지만 Cocoa 바인딩은 아직 iOS 에서 사용할 수 없다.




* 20.1.2. 키-값 코딩의 기본 동작


-

키-값 코딩을 위해 필요한 메서드는 비형식 프로토콜인 NSKeyValueCoding 에 선언되어 있다.


-(id) valueForKey:(NSString*)key

-(void) setValue:(id)value forKey:(NSString*)key




20.2. 프로퍼티에 접근


* 20.2.1. 키-값 코딩의 메서드 동작


-

밑줄로 시작하는 이름은 메서드명이나 인스턴스 변수명으로 사용하면 안 된다.

또한 get으로 시작하는 이름도 사용하면 안 된다.

KVC 에서 이용하기 때문이다.



-

name 이라는 키 문자열로 접근할 경우


1. 리시버에 name 접근자( 또는 getName, isName, _name, _getName 중 하나) 가 있으면 그것을 사용한다.

2. 접근자가 없으면 리시버 클래스에 메서드 accessInstanceVariablesDirectly 를 사용해서 문의한다. 여기서 YES 가 return 되면, 인스턴스 변수 name( 또는 _name, isName, _isName 중 하나 ) 가 있으면 그 값을 돌려준다.

3. 접근자도 인스턴스 변수도 없으면 리시버에 메서드 valueForUndefinedKey: 의 호출이 발생한다.

4. 반환할 값이 객체가 아니라면 적절한 객체로 래핑된 값이 반환된다.



-

리시버가 인덱스가 있는 접근자 패턴과 일치하는 메서드를 가지면 배열 객체로 행동하는 대리(프록시)객체가 반환된다.



-

인스턴스 변수에 대한 접근 여부를 결정하는 클래스 메서드와 값의 취득에 실패했을 때 호출되는 메서드는 다음과 같다.


+(BOOL) accessInstanceVariablesDirectly

 보통은 YES 를 돌려주도록 정의되어 있지만, 서브 클래스에서 변경할 수 있다.

 이 클래스 메서드가 YES 를 돌려주면 키-값 코딩에서 그 클래스의 인스턴스 변수에 접근할 수 있다.

 NO 일 때는 접근할 수 없다.

 한편 인스턴스 변수의 가시 속성이 @private 이더라도 이 메서드가 YES 를 돌려주면 접근할 수 있다.


-(id) valueForUndefinedKey:(NSString*)key

 키 문자열 key 에 대응하는 값을 얻을 수 없는 경우 메서드 valueForKey: 안에서 호출된다.

 기본적으로 이 메서드 실행은 예외 NSUndefinedKeyException 이 발생하지만 서브 클래스에서 재정의해서 다른 객체를 돌려줄 수도 있다.



-

name 이라는 키에 대한 setValue:forKey: 는..


1. 리시버에 setName: 이라는 접근자(또는 _setName:)가 있으면 그것을 사용한다. set 직후 키의 첫 글자는 반드시 대문자이다. 즉, setname: 은 인식하지 않는다.

2. 접근자가 없으면 리시버의 클래스에 메서드 accessInstanceVariablesDirectly 를 사용해서 문의한다. YES 를 return 하면 인스턴스 변수 name (또는 _name, isName, _isName 중 하나 ) 이 있으면 거기에 값을 설정한다. 카운터 관리 방식의 경우 인스턴스 변수가 객체라면 오래된 값은 자동 해제되고 새로운 값이 유지되어 대입된다.

3. 접근자도 인스턴스 변수도 없으면 리시버에 메서드 setValue:forUndefinedKey: 의 호출이 발생한다.

4. 설정해야 할 값이 객체가 아니면 적절하게 값 변환이 일어난다.



-

-(void) setValue:(id)value forUndefinedKey:(NSString*)key

 키 문자열 key 에 대응하는 프로퍼티 값을 설정할 수 없을 경우 메서드 setValue:forKey: 안에서 호출된다.

 기본적으로 이 메서드의 실행은 예외 NSUndefinedKeyException 을 발생시키지만 서브 클래스에서 재정의해서 다른 동작을 할 수도 있다.



-

키-값 코딩에서 넘겨받은 객체는 모두 id 형이 되므로 이 부분에서 컴파일할 때 형식 검사가 충분히 작동하지 않는다.

프로퍼티에 잘못된 객체를 넘기지 않도록 충분히 주의해야 한다.




* 20.2.2. 속성값의 자동 변환


-

단순한 값, 즉 섲수나 실수, 참/거짓 값 같은 것을 스칼라(scalar)값이라고 한다.

또한 스칼라 값, 구조체, 문자열이나 NSNumber 같은 변하지 않는 객체를 속성(attribute)라고 부른다.



-

키-값 코딩에서 다루는 속성에는 객체뿐만 아니라 스칼라값, 구조체 등도 포함된다.

valueForKey: 는 반환값이 스칼라값이나 구조체일 때 자동으로 래핑해서 객체를 돌려준다.

한편 setValue:forKey:에 값을 넘기려면 적절한 객체로 래핑해야 한다.



-

받아넘기는 값이 단순형, 즉 정수나 실수, 참/거짓형일 때는 NSNumber 클래스가 래핑에 사용된다.



-

구조체라면 NSValue 클래스의 인스턴스로 래핑한다.

자동으로 주고받을 수 있는 건 Cocoa 에서 표준적으로 사용되는 네 종류의 구조체인 NSPoint, NSRange, NSSize, NSRect 로 한정된다.

이외의 구조체나 포인터를 받을 때는 직접 접근자 메서드를 준비해야 한다.



-

프로퍼티 값이 객체일 경우 값으로 nil 을 주고받을 수 있다.

스칼라형 프로퍼티에 대해 setValue:forKey: 로 nil 을 설정하려고 할 때 리시버에 setNilValueForKey: 메시지가 송신된다.


- (void) setNilValueForKey:(NSString*)key

 키 문자열 key 에 대응하는 스칼라형 프로퍼티에 nil 이 설정될 때 메서드 setValue:forKey: 안에서 호출된다.

 기본적으로 이 메서드의 실행은 예외 NSinvalidArgumentException 을 발생시키지만 서브 클래스에서 재정의해서 다른 동작을 할 수 있다.




* 20.2.3. 사전 객체와 키-값 코딩


-

사전 클래스인 NSDictionary 와 NSMutableDictionary 는 프로토콜 NSKeyValueCoding 의 메서드를 제공해서 키-값 코딩에 대응한다.




* 20.2.4. 키 패스를 사용한 접근


-

KVC 로 얻은 객체에 또 다시 KVC 를 할 경우에 메서드를 겹쳐 쓰는 건 귀찮은 일이므로

키-값 코딩에서는 어떤 키를 사용해 접근해서 얻은 프로퍼티 객체에 다시 다른 키를 사용해서 접근할 경우 다음처럼 작성한다.

id name = [aGroup valueForKeyPath:@“leader.name”];


키를 .(도트)로 연결해서 표현하는 문자열을 키패스(key path)라고 부른다.

도트와 키는 객체가 연결만 되어 있으면 아무리 길어져도 괜찮다.



-

- (id) valueForKeyPath:(NSString*)keyPath

- (void) setValue:(id)value forKeyPath:(NSString*)keyPath




* 20.2.5. 다대일 관계와 다대다 관계


-

키(또는 키 패스)로 접근할 때 대상이 하나로 정해진 프로퍼티를 다대일 관계(to-one relationship)를 지정한 프로퍼티라고 한다.

한편, 프로퍼티값이 배열이나 집합일 때를 다대다관계(to-many relationship)를 지정한 프로퍼티라고 한다.



-

사전 객체는 다대일 관계이다.



-

1. 컬렉션 요소 객체가 가진 키를 사용해서 다대다 관계의 프로퍼티를 참조할 때 키에 대응하는 프로퍼티가 배열 또는 집합으로 반환된다.

2. 컬렉션의 요소 객체가 가진 키를 사용해서 다대다 관계의 프로퍼티에 값을 설정하면 각 요소 객체의 키에 대응하는 프로퍼티가 모두 변경된다.




* 20.2.6. 배열 객체와 키-값 코딩


-

배열 클래스인 NSArray 와 NSMutableArray 및 집합 클래스인 NSSet 과 NSMutableSet 은 프로토콜 NSKeyValueCoding 메서드로 키-값 코딩에 대응한다.


- (id)valueForKey:(NSString*)key

 컬렉션의 각 요소에 대응하여 key 를 인수로 한 메서드 valueForkey: 를 적용한 결과의 배열(NSSet 이라면 집합)이 반환된다.

 요소에 메서드 valueForKey: 를 적용한 결과가 nil 이면 NSNull 인스턴스가 포함된다.


- (void)setValue:(id)value forKey:(NSString*)key

 컬렉션의 각 요소에 대해 메서드 setValue:forKey: 를 호출한다.

 이 메서드는 컬렉션 객체 자체는 변경할 수 없더라도 호출되므로 주의해야 한다.






20.3. 다대다 관계의 접근


* 20.3.1. 인덱스가 있는 접근자 패턴


-

배열이 아닌 객체도 어떤 패턴의 접근자가 있으면 키-값 코딩에서 배열과 마찬가지로 다룰 수 있는 구조가 마련되어 있다.

이 접근자 패턴을 인덱스 있는 접근자 패턴(indexed accessor pattern)이라고 부른다.


구체적으로 다음 두 메서드를 구현한다.

밑줄 부분에는 키로 사용할 문자열이 들어간다.


- (NSUinteger)countOf____;

- (id)objectIn____AtIndex:(NSUInteger)index;



-

실행 효율을 올리기 위해 두 메서드 패턴에 더해 다음의 메서드를 구현할 수도 있다.

이것도 배열 클래스 클러스터인 getObjects:range: 와 비슷한 메서드이다.


-(void)get____:(id ____ unsafe_unretained[])aBuffer range:(NSRage)aRange;




* 20.3.2. 다대다 관계에 변경 가능한 접근


-

인덱스 있는 접근자 패턴을 구현하면 리시버 객체 안에서는 변경 불가능한 배열이 있는 것처럼 보일 수도 있다.

거기에 변경 가능한 배열이 있는 것처럼 보여줄 수도 있는데,

이런 변경 가능한 배열은 프로퍼티 요소 객체를 포함하는 것은 물론이고 배열 요소를 추가 또는 삭제하면 프로퍼티 요소도 연동해서 추가, 삭제된다.


- (NSMutableArray*)mutableArrayValueForKey:(NSString*)key

- (NSMutableArray*)mutableArrayValueForKeyPath:(NSString*)keyPath




-

위 메서드들로 프로퍼티를 조작하려면 앞에서 설명한 변경 불가능한 배열에 접근하는 두 메서드와 함께 삽입과 삭제를 위한 메서드를 구현한다.

밑줄 부분에는 키가 되는 문자열이 (보통은 복수형으로) 들어간다.

이런 메서드를 사용해서 키-값 코딩에 접근할 때 내부적으로 프록시가 움직여서 배열로 동작한다.


- (void)insertObject:(id)obj in____AtIndex:(NSUInteger)index;

- (void)removeObjectFrom____AtIndex:(NSUInteger)index;



-

위 두 메서드가 아니라 다음의 메서드 구현으로도 프로퍼티에 변경 가능한 접근이 된다.


- (void)set____:(id)anArray;


이 메서드 구현에서 인수로 전달된 배열 요소 객체로 다대다 관계의 프로퍼티 내용을 모두 바꿔 쓸 수 있다.



-

삽입과 삭제의 두 메서드로 구현했을 때와 비교하면 실행효율이 떨어지게 된다.

삽입과 삭제 메서드와 함께 다음 메서드를 구현하면 실행 효율이 좋아질 가능성이 있다.


- (void)replaceObjectIn____AtIndex:(NSUInteger)index withObject:(id)obj;



-

앞에서 본 메서드 중에서 아무것도 구현되어 있지 않을 때 키 문자열과 같은 이름의 인스턴스 변수가 있고 그것이 변경 가능한 배열 객체라고 하면 메서드 mutableArrayValueForKey: 는 그것을 반환값으로 사용한다.




20.4. KVC 준수


* 20.4.1. 프로퍼티 값 검증


-

검증 메서드는 자동 호출이 아니므로 프로퍼티에 접근하기 전에 스스로 호출해야 한다.



-

어떤 키 문자열에 대응하는 프로퍼티에 값을 검증하는 메서드는 다음과 같이 정의한다.

밑줄에는 키 문자열이 들어간다.

인수 ioValue 는 검증하고 싶은 객체의 포인터이다.

인수 outError 는 검증 결과에 문자가 있을 때 에러를 돌려주기 위한 인수이다.


- (BOOL) validate____:(inout id*)ioValue error:(out NSError**)outError;


검증하고 싶은 객체에 문제가 없으면 메서드는 YES 를 돌려주고 두 인수의 값은 변하지 않는다.

객체에 문제가 있더라도 객체의 값을 수정하면 유효한 값이 될 수 있을 때 메서드는 새로운 객체를 작성해서 원래 객체 대신에 ioValue 에 대입한다.

이 때 인수 outError 는 변하지 않고 반환값은 YES 가 된다.


객체에 문제가 있지만 수정도 할 수 없다면 에러 객체가 생성되어 인수 outError 에 대입된다.

메서드 반환값은 NO 이다.



-

프로퍼티에 값을 설정하는 접근자 메서드 (set____:) 안에서 자기 자신에 대한 검증 메서드를 호출하면 안 된다.



-

키가 실행될 때 동적으로 넘어올 경우에는 메서드명을 코드에 기입할 수 없다.

그런 경우에는 두 메서드를 이용할 수 있다.


-(BOOL) validateValue:(inout id*)ioValue forKey:(NSString*)key error:(out NSError**)outErr

 지정된 키를 사용해서 validate____:error: 의 검증 메서드를 찾아 호출한다.

 만약 그런 검증 메서드가 없으면 YES 를 돌려준다.


- (BOOL) validateValue:(inout id*)ioValue forKeyPath:(NSString*)keyPath (out NSError**)outError

 앞의 메서드와 다른 점은 키 패스를 지정한다는 것.

 실제로 호출되는 검증 메서드는 이 메서드의 리시버에 있는 것이 아니라 마지막 키 요소에 대응하는 프로퍼티의 검증 메서드라는 것에 주의.



-

카운터 관리 방식으로 메모리 관리를 할 때 검증 메서드 호출은 주의할 점이 있다.

검증 대상이 되는 객체도 에러 객체도 포인터로 참조되는데, 이런 값은 덮어쓸 가능성이 있다.

이 때 원래 객체는 명시적으로 해제되지 않음에도 어디에서도 참조하지 못하게 된다.

따라서 소유권이 유지된 객체를 넘길 때는 주의해야 한다.




* 20.4.2. 키-값 코딩 준수


-

어떤 프로퍼티에 대해 키-값 코딩을 사용한 접근이 가능하다는 것을 그 프로퍼티가 ‘키-값 코딩을 준수하고 있다’ 또는 ‘KVC를 준수(compliance)한다’라고 한다.

달리 말하면 KVC 준수인 것을 알고 있는 프로퍼티라면 키-값 코딩을 사용한 프로그래밍을 해도 괜찮다는 말이다.

이런 KVC 를 준수한다는 건 프로토콜 적합 개념과 달리 클래스 단위가 아닌 개별 프로퍼티 단위로 평가한다.



-

속성이 KVC 준수이려면 valueForKey: 가 가능하도록 접근자가 구현되어야 한다.

프로퍼티를 변경할 수 있을 때는 거기에 setValue:forKey: 에 대응한 접근자도 필요하다.



-

프로퍼티가 속성(스칼라값이나 단순형 객체) 또는 다대일 관계일 떄 KVC 준수가 되는 조건은 다음과 같다.

프로퍼티명이 ‘name’ 일 경우이다.


1. (a) name 또는 isName 이라는 접근자 메서드를 구현한다.

   (b) (a) 가 아니면 name (또는 _name)이라는 인스턴스 변수가 있다.

2. 변경 가능한 프로퍼티라면 setName: 도 구현한다.

 그 키에 대한 검증을 실시할 때는 검증 메서드 validateName:error: 를 구현한다.

 다만, setName: 메서드에서 검증 메서드를 호출해서는 안 된다.



-

프로퍼티가 다대다 관계일 때 KVC 준수가 되는 조건은 다음과 같다.

프로퍼티명이 ‘names’ 일 경우이다.


1. (a) 배열을 돌려주는 names 라는 메서드가 구현되어 있다.

  (b) (a) 가 아니면 names(_names) 라는 배열 객체를 유지하는 인스턴스 변수가 있다.

  (c) (a) 와 (b) 가 아니면 인덱스 있는 접근자 패턴의 메서드 countOfNames: 및 objectInNamesAtIndex: 를 구현한다.

2. 다대다 관계의 프로퍼티가 변경 가능할 경우

  (a) 변경 가능한 배열 객체를 돌려주는 names 메서드가 있다.

  (b) (a)가 아니면 인덱스 있는 접근자 패턴의 메서드 insertObject:inNamesAtIndex: 및 removeObjectFromNamesAtIndex: 를 구현한다.



-

두말 할 필요 없이 인덱스 있는 접근자 패턴의 메서드를 구현할 때 실행 효율을 높이려면 다른 메서드를 추가로 구현하는 것이 좋다.




20.5. 키-값 감시


* 20.5.1. 키-값 감시의 기본


-

키-값 감시(key-value observing)란 어떤 객체의 프로퍼티가 변화하는 걸 다른 객체에 전달하는 구조로, KVO 라고 한다.



-

키-값 감시는 감시 대상이 되는 객체에 감시하고 싶은 프로퍼티 키 패스와 감시하는 쪽의 객체(관찰자)를 등록한다.

프로퍼티가 변경되면 관찰자에 메시지가 전송된다.

NSNotification 알림과 비슷하지만 키-값 감시는 알림 센터에 해당하는 객체가 존재하지도 않고 보내는 메시지 셀렉터를 지정할 수도 없다.



-

키-값 감시 기능은 NSObject 에 구현되어 있어 속성, 다대일 관계, 다대다 관계 어떤 종류의 프로퍼티라도 감시할 수 있다.



-

감시 가능한 프로퍼티의 변화는 키-값 코딩에 준수한 방법으로 접근자 또는 인스턴스 변수에 접근할 때 뿐이다.

메서드 내부에서 인스턴스 변숫값을 직접 변경했을 경우에는 감시되지 않는다.

구체적으로 KVC 에 준거한 다음의 세 종류일 경우에만 KVO 가 제대로 작동한다.


1. 접근자 메서드로 변경한다.

2. setValue:forKey: 와 키를 사용해서 변경한다. 이 때 접근자를 경유하지 않을 수도 있다.

3. setValue:forKeyPath: 와 키 패스로 변경한다. 이 때 접근자를 경유하지 않을 수도 있다.

 또한 최종적인 감시 대상 프로퍼티뿐만 아니라 패스 도중의 프로퍼티가 변화했을 경우에도 알림 대상이 된다.



-

키-값 검사를 등록하는 메서드는..


- (void) addObserver:(NSObject*)anObserver forKeyPath:(NSString*)keyPath options:(NSKeyValueObserverationOptions)options context:(void*)context

 프로퍼티가 변화할 때 보내는 알림 메시지에는 변화 내용을 나타내는 사전 데이터와 인수 context 에 지정한 임의의 포인터(또는 객체)가 포함된다.

 options 는 사전 데이터에 어떤 값이 포함될지를 지정한다.

 값은 다음 상수 중 하나 또는 둘의 OR 연산이다.


 NSKeyValueObservingOptionNew : 프로퍼티가 변경된 후의 값을 제공

 NSKeyValueObservingOptionOld : 프로퍼티가 변경되기 전의 값을 제공



-

위 메서드로 감시를 지정한 프로퍼티에 변경이 있으면 관찰자에 다음 메시지가 전달된다.

모든 관찰자는 이 메서드를 구현해야만 한다.


- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context;


change 에 저장되는 항목의 키 문자열과 그 내용은 다음과 같다.


NSKeyValueChangeKindKey

 프로퍼티의 변경 종류를 나타낸다. 다음 세가지 값이 들어있다.

 NSKeyValueChangeInsertion : 삽입

 NSKeyValueChangeRemoval : 삭제

 NSKeyValueChangeReplacement : 치환


NSKeyValueChangeNewKey

NSKeyValueChangeOldKey


NSKeyValueChangeIndexesKey

 변경가능한 배열에 삽입, 삭제, 치환을 할 때 그런 조작이 일어난 인덱스 집합을 나타내는 클래스 NSIndexSet 의 인스턴스.



-

한번 등록한 감시를 멈추려면 다음 메서드를 사용한다.


- (void) removeObserver:(NSObject*)abObserver forKeyPath:(NSString*)keyPath


프로퍼티 감시를 등록할 떄 관찰자도, 감시 대상 프로퍼티도 유지되지 않는다.

또한 등록 정보를 삭제하지 않고 관련 객체를 해제시키면 프로퍼티 변경에 따라 이미 해제된 객체에 접근이 발생할 위험이 있다.




* 20.5.2. 예제 프로그램



* 20.5.3. 다대다 관계의 프로퍼티 감시


-

프로퍼티가 다대다 관계일 때도 감시 방법은 같다.

다만, 다대다 관계가 배열형이면 메서드 mutableArrayValueForKey: 를 사용하고, 집합형이면 메서드 mutableSetForkey: 를 사용해서 객체의 값을 변경해야만 감시가 가능하다. ( 메서드 ~ForKeyPath: 도 동일 )




* 20.5.4. 의존하는 키 등록


-

어떤 프로퍼티 값이 같은 객체의 다른 프로퍼티 변경에 따라 변화할 때가 자주 있다.

그런 의존 관계를 클래스마다 등록해둠으로써 간접적으로 값이 변화하는 프로퍼티에 대해서도 알림 메시지를 보낼 수 있다.


+ (void)setKeys:(NSArray*)keys triggerChangeNotificationsForDependentKey:(NSString*)dependentKey

 배열 keys 에는 여러 키를 지정할 수 있다.

 이런 키 중 어떤 것에 대응하는 프로퍼티에 변경이 있을 때 자동으로 키 dependentKey 의 프로퍼티에 대해서도 변경이 있을 때와 같은 동작(감시된다면 알림)이 발생하도록 의존 관계를 등록한다.




20.6. Cocoa 바인딩 개요


* 20.6.1. 타깃-액션 패러다임의 약점


-

‘부품에서 대상으로 메시지를 보낸다’ 라는 개념만으로는 대응할 수 없을 때도 많다.

특히 값 변화에 따라 여러 객체를 연계하려면 전용 코드를 작성해야만 한다.




* 20.6.2. Cocoa 바인딩이란


-

Mac OS X 10.3 부터 도입된 Cocoa 바인딩 ( Cocoa binding ) 은 키-값 코딩과 키-값 감시를 조합해서 여러 객체 사이에 프로퍼티 값 변화를 공유할 수 있는 구조이다.



-

iOS 에서는 사용할 수 없다.


다음 글 : [Objective-C] 기타




반응형

댓글