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

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

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

или это потому, что .NET имеет отражение и поэтому не нуждается в чем-то вроде кодирования ключей? Я могу схватить тип "anObject " и использовать отражение для цикла всех его свойств и искать тот, который называется "адрес", а затем использовать отражение для установки значения. Может быть, это аналогия KVC?

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

3 ответов


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

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

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

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

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

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


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

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

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

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

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

"позиции.x " в этом случае ссылается на позицию слоя,а в этой позиции это компонент X.

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

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

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

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


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

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);

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