Подтвердить что ты не робот

Что такое шаблон поиска KVC для mutableArrayValueForKey?

Я пытаюсь понять механизм Cocoa Key-Value Coding (KVC) немного лучше. Я читал Apple Руководство по программированию по ключевым параметрам, но я все же немного запутался в том, как некоторые методы KVC ищут ключи. В частности, mutableArrayValueForKey:.

Ниже я расскажу, как я понимаю valueForKey: KVC "getters" для работы. Затем я перейду к моему вопросу относительно mutableArrayValueForKey.


Существует семь различных методов "KETER": "/get >

- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;

При поиске значения внутри свойства (с именем myKey) Apple docs заявляет, что поиск valueForKey: выглядит следующим образом:

  • Выполняет -getMyKey, -myKey и -isMyKey (в этом порядке) внутри получателя
  • Если он не найден, он пытается получить эти упорядоченные множители (NSArray):

    // Required:
    - (NSUInteger)countOfMyKey;
    
    // Requires At Least One:
    - (id)objectInMyKeyAtIndex:(NSUInteger)index;
    - (NSArray *)myKeyAtIndexes:(NSIndexSet *)indexes;
    
    // Optional (improves performance):
    - (void)getMyKey:(KeyClass **)buffer range:(NSRange)inRange;
    
  • Затем он пытается использовать эти неупорядоченные гейтеры (NSSet):

    - (NSUInteger)countOfMyKey;
    - (NSEnumerator *)enumeratorOfMyKey;
    - (KeyClass *)memberOfMyKey:(KeyClass *)anObject;
    
  • Затем он пытается получить доступ к переменным экземпляра напрямую, предполагая, что YES возвращается accessInstanceVariablesDirectly в следующем порядке: _myKey, _isMyKey, myKey, isMyKey.

  • Наконец, он отказывается и вызывает метод получающего класса - (id)valueForUndefinedKey:(NSString *)key. Обычно здесь возникает ошибка.


Мой вопрос: каков шаблон порядка поиска для mutableArrayValueForKey:?

Apple docs заявляет об этом:

Шаблон поиска доступа для заказа Коллекции

Шаблон поиска по умолчанию для mutableArrayValueForKey: как следующим образом:

В классе приемника выполняется поиск пара методов, имена которых соответствуют pattern -insertObject: inAtIndex: и -removeObjectFromAtIndex: (соответствует NSMutableArray примитивные методы insertObject: atIndex: и removeObjectAtIndex: соответственно), или методы, соответствующие шаблону -insert: atIndexes: and -removeAtIndexes: (соответствует NSMutableArrayinsertObjects: atIndexes: и removeObjectsAtIndexes: методы). Если хотя бы один метод вставки и найдены хотя бы один метод удаления каждое сообщение NSMutableArray, отправленное объект прокси-объекта коллекции приводят к некоторой комбинации -insertObject: inAtIndex:, -removeObjectFromAtIndex:, -insert: atIndexes:, and -removeAtIndexes: сообщения, отправляемые исходному приемнику mutableArrayValueForKey:.... и т.д...

Это не имеет никакого смысла для меня, поскольку он обсуждает "setter", как методы. mutableArrayValueForKey: возвращает NSMutableArray. Все перечисленные выше методы возвращают void и используются для редактирования NSMutableArray, а не для его получения. Пример:

- (void)insertMyKey:(KeyClass *)keyObject inMyKeyAtIndex:(NSUInteger)index;
- (void)removeObjectFromMyKeyAtIndex:(NSUInteger)index;

Любая идея, которую Apple пытается сказать в своих документах, или, возможно, это ошибка?

Моя теория состоит в том, что mutableArrayValueForKey:, вероятно, будет придерживаться аналогичного пути valueForKey: при поиске для получения значения KVC. Я просто не уверен, какой путь на самом деле.

Спасибо за любую помощь, которую вы можете предложить!:)

4b9b3361

Ответ 1

NSMutableArray, который вы возвращаете из вызова mutableArrayValueForKey:, фактически является частным подклассом NSMutableArray, который переопределяет обычные методы массива, такие как -count, -objectAtIndex:, -insertObject:atIndex: и т.д., и вызывает соответствующий KVC методы на объекте, из которого был получен массив. Он в основном действует как прокси-сервер для манипулирования отношениями ко многим ко многим объектам, и вам не нужно беспокоиться о создании или возврате себя. Быстрый пример использования:

Playlist* aPlaylist;
Track* aTrack;
NSMutableArray* mutableTracks = [aPlaylist mutableArrayValueForKey:@"tracks"];
[mutableTracks insertObject:aTrack atIndex:0];

Этот фрагмент кода добавляет дорожку в начало списка воспроизведения. Если класс Playlist реализует методы KVC для своих отношений "треки", вызов метода в изменяемом массиве приведет к вызову соответствующего метода для базового объекта. Поэтому в этом примере, когда вы вызываете insertObject:atIndex: в массиве, массив будет в свою очередь вызывать insertObjectInTracks:atIndex: в объекте списка воспроизведения, а трек добавляется в массив плейлистов треков.

Теперь в этом примере, конечно, вы можете просто вызвать insertObjectInTracks:atIndex: напрямую, но есть несколько преимуществ, которые вы можете использовать вместо mutableArrayValueForKey:.

  • Обертка массива скрывает детали реализации базовых методов KVC. Внедрение всего списка методов строго не требуется, чтобы соответствовать требованиям KVC. Класс Playlist может просто реализовать -tracks и -setTracks:, а код выше будет работать. В этом случае вместо вызова insertObjectInTracks:atIndex: прокси-сервер mutable array создаст новый массив с объектом, вставленным в начале, а затем просто вызовет setTracks: в объекте Playlist. Это, очевидно, менее эффективно, поэтому рекомендуется использовать полный список методов KVC.
  • В случае, когда вместо константной строки для ключа вместо вас есть переменная, использование mutableArrayValueForKey: позволяет вам манипулировать отношениями без необходимости знать точные имена методов, которые вы должны вызывать. Пока объект соответствует KVC для ключа, который вы используете, все будет "просто работать".
  • Он также позволяет использовать любой метод, который реализует NSMutableArray, поэтому вы можете использовать методы, которые ищут массив для объектов, сортируют массив и т.д., не переписывая специальные версии для работы с материалами KVC.