Кодирование ключевых значений Apple - может кто-нибудь объяснить разработчику C #, зачем мне это нужно и что оно делает? - PullRequest
7 голосов
/ 26 февраля 2012

Прежде чем перейти к разработке под iOS через Monotouch, я немного поиграл с ObjectiveC. С тех пор как я вспомнил одну вещь "Код значения ключа" (KVC) . Я никогда не понимал, для чего это хорошо и в чем заключается магия.

Насколько я понимаю, это просто набор имен и значений, например .NET NameValueCollection: вместо установки anObject.Address = "An address Value" вы бы написали anObject.Properties["Address"] = "An address value". Отлично. И что? Потому что это кажется мне слишком простым, я уверен, что это не может быть.

Или это потому, что в .NET есть отражение и, следовательно, не нужно что-то вроде Key-Value-Coding? Я могу взять тип «anObject» и использовать отражение, чтобы зациклить все его свойства, найти то, что называется «Адрес», а затем использовать отражение, чтобы установить значение. Может быть, это аналогия KVC?

Я надеюсь, что есть кто-то, кто является профессионалом в ObjC и C # / .NET, кто может объяснить мне, каковы преимущества и как это перевести на .NET. Пожалуйста, не указывайте мне документацию Apple. Я все это знаю. Я пытаюсь выяснить, чего-то не хватает в моей жизни кодирования, не зная KVC? Или, может быть, я использовал что-то подобное в .NET, не зная, что это приведет к KVC, если я использую ObjC?

Ответы [ 3 ]

11 голосов
/ 26 февраля 2012

От кого-то, кто использует их каждый день в течение, вероятно, 3 лет:

Как вы поняли, в KVC нет ничего удивительно сложного, что нельзя сделать с помощью словарей и NameValueCollections в C #.

Большая разница в том, что KVC построен на языке.Объект в Obj-C IS a NameValueCollection.Вам не нужно менять способ разработки (от классов и свойств до словарей), чтобы использовать его.Вы можете создать свой объект с нужными вам свойствами, а затем вызвать valueForKey: @ "name", и все будет работать.

Теперь вы можете сказать: "да, круто, но я могу сделать это сотражение!».Конечно, вы можете, но так же, как и раньше, вам придется снова изменить способ своего развития, не считая того факта, что отражение в целом намного медленнее.

Еще одна интересная особенность KVC - она ​​позволяет вамиспользуйте KVO, который в основном позволяет вам регистрироваться для получения уведомлений об изменениях в любом объекте без необходимости писать одну строку кода в этих объектах.Таким образом, в любом объекте вашего приложения вы можете вызвать «addObserver: forKeyPath:» и получить обратный вызов, если кто-либо еще в вашем приложении изменит это свойство.Это действительно полезно для живых приложений, таких как приложения для iOS.

Опять же, вы можете реализовать KVO в C # (например, инфраструктуры MVVM делают это постоянно), но для этого нужно написать дополнительный код.В Obj-C он построен на языке.

7 голосов
/ 26 февраля 2012

Я писал об этом в контексте MonoMac, однорангового проекта MonoTouch, но использовался для создания приложений Mac:

http://tirania.org/monomac/archive/2010/Dec-07.html

Кодирование значения ключа - это наборпрактики, которые позволяют приложениям получать доступ к свойствам объекта, используя строки.Это похоже на Binding Expressions в Silverlight.В обоих случаях цель состоит в том, чтобы предоставить инструментам, которые не имеют прямого доступа к вашему нативному коду, доступ к свойствам из вашей программы.

В частности, это полезно, поскольку некоторые API могут воспользоваться этим.Например, CoreAnimation может анимировать свойства с учетом их «пути» к объекту.Например, вы можете сделать:

var animateX = CAKeyFrameAnimation.FromKeyPath ("position.x");
pos.Values = new NSNumber [] { 0, 10, 60 };
layer.AddAnimation (animateX, "move");

«position.x» в этом случае ссылается на позицию слоя, а внутри этой позиции - его компонент X.

Пост блога, приведенный выше, переходит вПодробнее о том, как вы можете на самом деле выставлять свои собственные объекты для участия в этом протоколе (регистрация ваших собственных свойств, чтобы сделать их видимыми для системы Key-Value-Coding).

Кеннет, еще один из разработчиков MonoMac, в блогеоб этом подробно здесь:

http://cocoa -mono.org / archives / 153 / kvc-kvo-and-cocoa-bindings-oh-my-part-1 /

В частности, он имеет дело со сходством с Reflection и показывает, как использовать [Экспорт], чтобы превратить ваш код C # в код, совместимый с KVC.

4 голосов
/ 26 февраля 2012

Если вы получите доступ к такому свойству

anObject.Address = "An address Value"

Код будет очень "статичным".Он всегда будет иметь доступ к Address

Вы можете создать более динамический код, подобный этому

void SetProperty (string propertyName, string value)
{
    anObject.Properties[propertyName] = value;
}

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

В c # вы обычно используете Dictionary<TKey,TValue> для хранения пар ключ / значение.Автоматический доступ к свойствам через KVC, как в Objective-C, не поддерживается в c #.Вы должны либо объявить свойство как

public Dictionary<string,string> Properties { get; private set; }

и создать его экземпляр в конструкторе класса с помощью

Properties = new Dictionary<string,string>();

, а затем получить к нему доступ

anObject.Properties[propertyName] = value;

вам нужно будет использовать Reflection для доступа к свойству

Type type = anObject.GetType();
// Or   Type type = typeof(TypeOfAnObject);
PropertyInfo prop = type.GetProperty(propertyName);
prop.SetValue(anObject, propertyValue, null);

Однако это не очень эффективно.

...