В чем разница между KVC и Properties? - PullRequest
8 голосов
/ 19 ноября 2011

Итак, я уже прочитал документацию, в которой отмечается

Точечный синтаксис Objective-C 2.0 и кодирование значения ключа являются ортогональными технологиями.Вы можете использовать кодирование ключ-значение независимо от того, используете ли вы точечный синтаксис, и можете использовать точечный синтаксис независимо от того, используете ли вы KVC или нет.Оба, тем не менее, используют «точечный синтаксис». В случае кодирования значения ключа синтаксис используется для разделения элементов в ключевом пути.Важно помнить, что когда вы обращаетесь к свойству с использованием точечного синтаксиса, вы вызываете стандартные методы доступа получателя.

Затем приводится пример, который предположительно показывает разницу между ними.Тем не менее, я до сих пор не понимаю, в чем разница между KVC и методами доступа к свойствам?Разве они не одинаковы?И как мне отличить точки, которые вызывают setValue: forKeyPath: и простые методы доступа?

Ответы [ 2 ]

15 голосов
/ 19 ноября 2011

Однако, я все еще не понимаю, в чем разница между KVC и методами доступа к свойствам?

KVC - это способ вызова методов доступа к свойству или иного доступа к свойству.

Что я подразумеваю под «иным доступом»? В целях KVC переменная экземпляра без методов доступа считается неформальным свойством. Он получит или установит значение переменной экземпляра напрямую, если не найдена соответствующая пара средств доступа. (Да, это не стоит использовать в современном коде. Всегда объявляйте @property для всего, к чему вы хотите получить доступ в другом месте, и, наоборот, не используйте KVC для доступа к чему-либо, что не является публичной собственностью.)

Методы доступа к свойствам - это то, что KVC будет вызывать, если они существуют (предпочтительнее, как KVC, так и каждым здравомыслящим программистом, по сравнению с прямым доступом к ivar). Метод доступа может получить или установить переменную экземпляра, как это делают синтезированные методы доступа, или получить доступ к некоторому другому хранилищу.

Средства доступа - это реализация, свойства - это интерфейс, и KVC - это один из способов их использования.

А как мне отличить точки, которые вызывают setValue: forKeyPath: и простые методы доступа?

Путь ключа - это строка, тогда как выражение доступа к свойству - это выражение. Компилятор оценивает выражение доступа к свойству и переводит его в одно или несколько сообщений Objective-C, тогда как путь ключа оценивается KVC во время выполнения.

Итак, когда вы используете путь ключа:

[someObject setValue:theValue forKeyPath:@"foo.bar.baz"];

Вы знаете, что это ключевой путь, потому что (1) это строка, как указано в данном случае строковым литеральным синтаксисом @"…", и (2) вы передаете строку ключевого пути в setValue:forKeyPath: для это оценить.

Использование ключевого пути - это использование KVC для доступа к именованным свойствам. Он будет отправлять любые соответствующие сообщения доступа от вашего имени.

Когда вы используете выражение доступа к свойству:

someObject.foo.bar.baz = theValue;

Вы знаете, что это выражение доступа к свойству, потому что вы не отождествляете свойства со строкой. Вы обращаетесь к ним (отправляете сообщения доступа) самостоятельно, в своем собственном коде.

Нет особых оснований использовать KVC в любой форме; если вы знаете свойство во время авторства / компиляции, лучше всего объявить @property и получить доступ к свойству самостоятельно, будь то с помощью выражений доступа к свойству или выражений сообщений ([[[someObject foo] bar] setBaz:theValue]). Время использования KVC - это когда вы не знаете, к какому свойству вы хотите получить доступ, до времени выполнения, что довольно редко. В основном это технология строительных блоков, лежащая в основе KVO, привязок какао, частей Core Animation и т. Д.

В большинстве случаев вы захотите получить доступ к свойствам только сами.

2 голосов
/ 19 ноября 2011

Кодирование значения ключа позволяет вам установить и получить значение свойств через код, используя строковое имя свойства.Например, если у меня есть свойство с именем foo, которое имеет тип NSString:

[self setValue:@"mystring" forKey:@"foo"];

// read the value by key
NSString *s =  [self valueForKey:@"foo"];

Синтаксис точки - это сахар синтаксиса компиляции.В качестве личного предпочтения (поскольку некоторые не согласны - хорошо), я не использую точечный синтаксис, но я все еще использую KVC:

[myObj setFoo: @"someString"]

равно:

myObj.foo = @"someString";

Они ортогональныразличные концепции, но оба касаются того, как вы взаимодействуете со свойствами

Наконец, вы упоминаете синтаксис свойства.Еще одно ортогональное понятие, но связанное с работой со свойствами.

С целью-c, соглашение важно.Следуйте за ними.Свойства - это имя свойства для получения и установки [Имя] для назначения:

- (NSString*)foo
{
    return _foo;  // defined as (NSString*)_foo in header
}

- (void) setFoo: (NSString*)foo
{
    if (foo == _foo)
        return;

    NSString* curr = _foo;

    _foo = [foo retain];
    [curr release];    
}

Теперь, кто хочет писать что-то подобное каждый раз.Итак, введите синтаксис @property:

В заголовке:

@property (retain) NSString *foo;

Затем в .m:

@synthesize foo;

Это эквивалент рукописных методов доступа к свойствам.Это синтаксический сахар компилятора, который расширяет код свойства в зависимости от того, как вы атрибутируете свойства.

Документы:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

...