티스토리 뷰

Key-Value Coding Programming Guide - Adopting Key-Value Coding  - Defining Collection Methods

표준 이름 규칙을 따르는 접근자나 인스턴스 변수를 만들면, KVC 프로토콜의 기본 구현은 그걸 사용 할수 있습니다. 이것은 일대다인 콜랙션 객체에도 적용됩니다. 그러나, 콜랙션접근 자 메소드를 만들면 다음에 나오는 내용을 할 수 있습니다.


- Model to - many relationships with classes other than NSArray or NSSet.

collection methods를 만들면, key-value getter의 기본구현은 proxy 객체를 리턴합니다. 이 객체는 NSArray 또는 NSSet 메시지에 반응하는 메소드를 호출합니다. 기본 프로퍼티 객체는 NSArray 또는 NSSet필요가 없습니다. 왜냐하면 프록시 객체가 컬렉션 메소드를 사용하여 예상되는 동작을 제공하기 때문입니다.


- Achieve increased performance when mutating the contents of a to-many relationship.

모든 변화에 대응해서 새로운 객체를 만드는 것 대신에, 프로토콜의 기본현은 콜렉션 메소드를 사용해서 객체를 수정합니다. 


- Provide key-value observing compliant access to the contents of your object's collection properties

kvo를 사용할 때 객체의 콜렉션 프로퍼티들의 요소에 접근하게 해줍니다.


아래에 나올 콜렉션 접근자의 두 개의 카테고리(array or set) 중 하나를 구현합니다. 어느 것을 하더라도 최소한 프로퍼티에 접근할 메소드 한 셋을 구현해야 합니다. 그 다음에 추가적으로 콜렉션 요소를 수정할 set을 추가합니다.


KVC 포로토콜에는 이 섹션에 나오는 메소드가 없습니다. 대신에 NSObject에서 제공하는 프로토콜의 기본구현은 KVC를 사용하는 객체에서 메소드를  Accessor Search Patterns에 나온대로 찾습니다. 그리고 kvc 메시지를 처리합니다.



Accessing Indexed Collections

접근자 메소드를 추가해서  counting, retrieving, adding, and replacing objects을 지원합니다. 기본 객체를 NSArray나 NSMutableArray의 인스턴스이지만, 콜렉션 접근자를 사용하면, 객체도 array처럼 다룰 수 있습니다. 


Indexed Collection Getters

기본 getter가 없는 콜렉션 프로퍼티에 대해서, 다음에 나오는 indexed collection getter 메소드를 제공하면 valueForKKey: 메시지에 대응하는 프로토콜의 기본 구현은 proxy 객체를 반환합니다. 이 객체는 NSArray처럼 동작합니다. 그러나 그렇게 하기 위해서는 다으음에 나오는 콜렉션 메소드들을 호출해야 합니다. 


!NOTE

현대 objective-c에서는 컴파일러가 각 프로퍼티마다 기본적으로 getter를 생성해 줘서, 기본 구현은 이 섹션에 나오는 메소드를 사용하는 read only proxy를 만들지 않습니다.  컴파일러가 자동생성 하는 걸 막기 위해서는 프로퍼티를 선언하지 않거나 @dynamic 지시자를 프로퍼티에 붙여줍니다. @dynamic은 런타임에 접근자를 만들겠다고 컴파일러에게 말해줍니다. 두 방법 모두 컴파일러가 기본 getter를 만들지 않게 합니다. 그리고 기본 구현은 아래 나오는 메소드를 사용합니다.


-countOf<Key>

이 메소드는 일대다 관계에 있는 객체의 갯수를  NSUInteger(unsigned) 리턴합니다. (NSArray의 count같은)


  1. - (NSUInteger)countOfTransactions {
  2. return [self.transactions count];
  3. }

- objectIn<Key>AtIndex: or <key>AtIndexes:

첫 번째는 일대다 관계에 있는 프로퍼티의 특정 index에 있는 객체를 리턴하고, 두 번째는 특정 인덱스들에 있는 객체를 배열로 반환합니다. NSArray의 objectAtIndex와 objectsAtIndexes랑 같죠. 둘 중 하나만 구현하면 됩니다.


  1. - (id)objectInTransactionsAtIndex:(NSUInteger)index {
  2. return [self.transactions objectAtIndex:index];
  3. }
  4. - (NSArray *)transactionsAtIndexes:(NSIndexSet *)indexes {
  5. return [self.transactions objectsAtIndexes:indexes];
  6. }

get<Key>:range:

이 메소드는 선택적으로 구현하면 됩니다. 구현하면 퍼포먼스가 올라갑니다. 컬렉션에서 지정된 범위 내에 있는 객체들을 반환합니다. 반환해서 buffer객체에 넣어줍니다.


  1. - (void)getTransactions:(Transaction * __unsafe_unretained *)buffer
  2. range:(NSRange)inRange {
  3. [self.transactions getObjects:buffer range:inRange];
  4. }


Indexed Collection Mutators

indexed 접근자와 함께 변경 가능한 일대다 관계를 지원하기 위해서는 다른 메소드들은 구현해야 합니다. 이 setter 메소드들을 만들면, mutableArrayValueForKey: 메시지 반응해서 proxy객체를 반환합니다. 이객체는 NSMutableArray처럼 작동하지만, 객체에 구현된 메소드를 사용해야 합니다. 그래야 더 효과적입니다. 그리고 KVO에도 대응할 수 있습니다.


- insertObject:in<Key>AtIndex: or insert<Key>:atIndexes:

첫 번째는 객체를 받아서 index에 넣습니다. 두 번째는 객체 배열을 indexes(NSIndexSet)에 넣습니다. NSMutableArra메소드의 insertObject:atIndexs:와 insertObjects:atIndexes와 같습니다 둘 중 하나만 구현하면 됩니다.


  1. - (void)insertObject:(Transaction *)transaction
  2. inTransactionsAtIndex:(NSUInteger)index {
  3. [self.transactions insertObject:transaction atIndex:index];
  4. }
  5. - (void)insertTransactions:(NSArray *)transactionArray
  6. atIndexes:(NSIndexSet *)indexes {
  7. [self.transactions insertObjects:transactionArray atIndexes:indexes];
  8. }

- removeObjectFrom<Key>AtIndexe: or remove<Key>AtIndexes:

첫 번째는 삭제할 index를 받고 두 번째는 삭제할 indexes(NSIndexSet)을 받습니다. 


  1. - (void)removeObjectFromTransactionsAtIndex:(NSUInteger)index {
  2. [self.transactions removeObjectAtIndex:index];
  3. }
  4. - (void)removeTransactionsAtIndexes:(NSIndexSet *)indexes {
  5. [self.transactions removeObjectsAtIndexes:indexes];
  6. }

- replaceObjectIn<Key>AtIndex:withObject: or replace<Key>Indexes:with<Key>:

이 메소드는 replace하는데 제거 하고 삽입하는 과정없이 바로 교체할 수 있습니다. NSMutableArray 메소드의 replaceObjectAtIndex:withObject:and replaceObjectsAtIndexes:withOjects:와 같습니다. 이 메소드는 앱 프로파일링을 통해서 퍼포먼스 이슈가 있다면 선택적으로 제공해주면 됩ㄴ다.



  1. - (void)replaceObjectInTransactionsAtIndex:(NSUInteger)index
  2. withObject:(id)anObject {
  3. [self.transactions replaceObjectAtIndex:index
  4. withObject:anObject];
  5. }
  6. - (void)replaceTransactionsAtIndexes:(NSIndexSet *)indexes
  7. withTransactions:(NSArray *)transactionArray {
  8. [self.transactions replaceObjectsAtIndexes:indexes
  9. withObjects:transactionArray];



Accessing Unordered Collections

unordered 콜렉션 접근자를 제공하면 unordered relatonship에서 객체에 접근하고 수정하는 방식을 쓸 수 있습니다. 보통 NSSet과 NSMutableSet 객체에 해당합니다. 그러나 NSSet이 아니더라도 이런 접근자를 제공하면 다른 클래스들도 NSSet처럼 사용할 수 있습니다.

Unordered Collection Getters

다음에 나오는 getter 메소드들을 만들면, 콜렉션에서 객체의 count를 리턴해주고, 콜렉션 객체를 반복해서 리턴하고, 컬렉션에 있는지 테스트합니다. valueForKey: 메시지에 반응하는 프로토콜의 기본구현은 proxy객체를 리턴합니다. 이 객체는 NSSet과 같이 동작하지만 객체네 구현된 메소드를 호출해야 합니다.

!NOTE

현대 objective-c에서는 컴파일러가 각 프로퍼티마다 기본적으로 getter를 생성해 줘서, 기본 구현은 이 섹션에 나오는 메소드를 사용하는 read only proxy를 만들지 않습니다.  컴파일러가 자동생성 하는 걸 막기 위해서는 프로퍼티를 선언하지 않거나 @dynamic 지시자를 프로퍼티에 붙여줍니다. @dynamic은 런타임에 접근자를 만들겠다고 컴파일러에게 말해줍니다. 두 방법 모두 컴파일러가 기본 getter를 만들지 않게 합니다. 그리고 기본 구현은 아래 나오는 메소드를 사용합니다.


-countOf<Key>

콜렉션의 count를 리턴


  1. - (NSUInteger)countOfEmployees {
  2. return [self.employees count];
  3. }

-enumeratorOf<Key>

NSEnumerator를 리턴해서 콜렉션에 있는 객체를 반복할 수 있습니다?

NSEnumberator를 더 자세히 알고 싶으시면 Collections Programming Topics 에 있는 Enumeration:Traversing a Collection's Elements를 보면 됩니다.


https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Collections/Articles/Enumerators.html#//apple_ref/doc/uid/20000135


  1. - (NSEnumerator *)enumeratorOfEmployees {
  2. return [self.employees objectEnumerator];
  3. }

-memberOf<Key>:

파라미터로 보내진 객체가 콜렉션에 있는지 확인하고 매칭된 객체를 리턴합니다. 없으면 nil를 리턴합니다. 비교를 수동으로 할 경우에는 isEqual:를 사용합니다. 객체가 NSSet이면 member:를 사용할 수 있습니다.


    1. - (Employee *)memberOfEmployees:(Employee *)anObject {
    2. return [self.employees member:anObject];
    3. }


Unordered Collection Mutators


unordered 접근자와 함께 변경 가능한 일대다 관계를 지원하기 위해서는 추가적으로 다른 메소드들은 구현해야 합니다. 변경가능한 unordered 접근자를 구현하면 mutableSetValueForKey:메소드에 반응하는 unordered set proxy객체를 제공할 수 있습니다. 이 접근자 메소드들은, mutable 객체를 리턴하는 접근자보다 효과적입니다. 그리고 KVO에도 대응할 수 있습니다.


- add<Key>Object: or add<Key>:

단일 아이템이나 아이템들은 추가합니다. 추가 할 때는 겹치는 아이템이 없는지 확인해야 합니다. 둘 중 하나만 만들면 됩니다. (NSMutableSet 메소드의 addObject: and unionSet: 과 비슷합니다.)


  1. - (void)addEmployeesObject:(Employee *)anObject {
  2. [self.employees addObject:anObject];
  3. }
  4. - (void)addEmployees:(NSSet *)manyObjects {
  5. [self.employees unionSet:manyObjects];
  6. }



- remove<Key>Object: or remove<Key>:

단일 아이템이나 아이템들은 삭제합니다.  (NSMutableSet 메소드의 removeObject: and minusSet: 과 비슷합니다.) 둘 중 하나만 만들면 됩니다.


  1. - (void)removeEmployeesObject:(Employee *)anObject {
  2. [self.employees removeObject:anObject];
  3. }
  4. - (void)removeEmployees:(NSSet *)manyObjects {
  5. [self.employees minusSet:manyObjects];
  6. }


- intersect<Key>:

이 메서드는 NSSet 매개 변수를 입력받으면, 기존 컬렉션 set과 입력set에 공통적이 않은 모든 객체를 제거합니다. NSMutableSet intersectSet과 같습니다. 이 메소드는 앱 프로파일링을 통해서 퍼포먼스 이슈가 있다면 선택적으로 제공해주면 됩ㄴ다.


  1. - (void)intersectEmployees:(NSSet *)otherObjects {
  2. return [self.employees intersectSet:otherObjects];
  3. }


반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함