KVC — кодирование значения ключа с разделением точками — исключение, несовместимое с KVC

@interface MyClass: NSObject
@property NSArray *arr;
@end
@inplementation MyClass
- (instancetype) init
{
    if(self = [super init])
    {
        self.arr = [[NSArray alloc] init];
    }
    return self;
}
@end
int main(int argc, char *argv[])
{
    MyClass *temp = [[MyClass alloc] init];
    [temp valueForKey:@"arr.count"];    //count is ivar of NSArray
    return 0;
}

затем консоль говорит

NSExceptions: [MyClass valueForUnfinedKey:] этот класс не является ключевой жалобой на значение для ключа arr.count

Каждый раз, когда я использую разделение точками, выходит это exceptions.

Я пытался искать в Интернете и читать меню, я до сих пор не знаю, почему, может ли кто-нибудь помочь? Спасибо.


person Bill Sun    schedule 30.10.2017    source источник


Ответы (2)


Метод valueForKey: принимает имя одного ключа (свойства или локальной переменной), он не использует ключевой путь, такой как ваш arr.count.

Метод valueForKeyPath: использует ключевой путь, фактически он представляет собой последовательность вызовов valueForKey:. См. раздел Получение значений атрибутов с помощью ключей в О кодировании "ключ-значение".

Однако ваш пример по-прежнему не будет работать из-за способа определения valueForKey: для NSArray:

Возвращает массив, содержащий результаты вызова valueForKey: с использованием ключа для каждого из объектов массива.

Таким образом, в вашем случае, если вы попробуете valueForKeyPath:@"arr.count", часть пути arr вернет ваш массив, а затем valueForKey: NSArray попытается получить ключ count для каждого элемента массива и нет для самого массива. Не то, что ты хочешь...

Что приводит нас к Операторы коллекций, которые предоставляют ключевые пути, которые работают с коллекцией, массивом в вашем случае, а не с ее элементами. Оператор сбора, который вам нужен, это @count, дающий вам ключевой путь arr.@count, поэтому вам нужно позвонить:

[temp valueForKeyPath:@"arr.@count"]

Если это не упражнение по изучению KVC, его можно сократить до:

temp.arr.count

который не пытается применить count к элементам массива и возвращает значение NSUInteger, а не экземпляр NSNumber.

ХТН

person CRD    schedule 30.10.2017
comment
Большое вам спасибо, сначала я даже не знаю разницы между valueForKey: и valueForKeyPath: и думаю, что они одинаковы, я пытался использовать valueForKeyPath:, но потерпел неудачу, потому что забыл, что это объект коллекции. Это помогает :) - person Bill Sun; 30.10.2017

Это потому, что arr.count не является ключевой жалобой MyClass. Когда программа запускается, она не может найти какое-либо свойство имени MyClass arr.count.

valueForKeyPath: — возвращает значение для указанного пути ключа относительно получателя. Любой объект в последовательности пути ключа, который не соответствует кодированию ключ-значение для определенного ключа, то есть для которого реализация по умолчанию valueForKey: не может найти метод доступа, получает сообщение valueForUndefinedKey:.

person trungduc    schedule 30.10.2017
comment
Спасибо, теперь я понимаю. - person Bill Sun; 30.10.2017