Каков Шаблон поиска KVC для mutableArrayValueForKey?

Я пытаюсь понять механизм Кодирования значения ключа (KVC) Какао немного лучше. Я прочитал Руководство по программированию Значения ключа Apple, но все еще немного перепутан тем, как определенные методы KVC ищут ключи. Особенно, mutableArrayValueForKey:.

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


Существует семь других "методов считывания" методы KVC:

- (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 указывают что valueForKey: поиски как это:

  1. Попытки -getMyKey, -myKey, и -isMyKey (в том порядке) в получателе
  2. Если не найденный, это делает попытку их заказанных, к - много методов считывания (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;
    
  3. Затем, это делает попытку их незаказанных, к - много методов считывания (NSSet):

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

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


Мой вопрос, что является поисковым шаблоном порядка для mutableArrayValueForKey:?

Документы Apple указывают это:

Шаблон поиска средства доступа для заказанных наборов

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

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

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

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

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

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

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

16
задан k06a 30 May 2016 в 13:57
поделиться

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 для своего отношения "tracks", то вызов метода на изменяемом массиве приведет к вызову соответствующего метода на базовом объекте. Поэтому в данном примере, когда вы вызываете insertObject:atIndex: на массиве, массив в свою очередь вызовет insertObjectInTracks:atIndex: на объекте плейлиста, и трек будет добавлен в массив треков плейлиста.

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

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

Похожие вопросы: