Что такое шаблон поиска 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. Я просто не уверен, какой путь на самом деле.
Спасибо за любую помощь, которую вы можете предложить!:)
Ответы
Ответ 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.