Apple的键值编码 - 有人可以向C#开发人员解释为什么我需要这个以及它的作用吗?

本文关键字:作用 解释 编码 键值 可以向 Apple 开发 为什么 | 更新日期: 2023-09-27 18:25:44

在我通过Monotouch切换到iOS开发之前,我玩了一下ObjectiveC。从那以后,我一直在想一件事"键值编码"(KVC(。我一直不明白它有什么好处,它背后的魔力是什么。

据我了解,它只是名称和值的集合,例如.NET的NameValueCollection:与其设置anObject.Address = "An address Value",不如写anObject.Properties["Address"] = "An address value"。伟大。那又怎样?因为这对我来说似乎太容易了,我敢肯定不可能。

还是因为 .NET 具有反射,因此不需要键值编码之类的东西?我可以获取" anObject"的类型并使用反射循环其所有属性并查找名为"地址"的属性,然后使用反射来设置值。这也许是KVC的类比吗?

我希望有人是 ObjC 和 C#/.NET 的专业人士,他可以向我解释好处是什么以及它如何转化为 .NET。请不要只是把我指向苹果的文档。我都知道。我试图找出到目前为止我的编码生活中是否因为不知道 KVC 而缺少了什么?或者我是否一直在 .NET 中使用类似的东西,而不知道如果我使用 ObjC,它会转换为 KVC?

Apple的键值编码 - 有人可以向C#开发人员解释为什么我需要这个以及它的作用吗?

来自每天使用两者的人,现在可能已经有 3 年了:

正如你所发现的,KVC 中没有什么惊人的复杂是 C# 中的字典和 NameValueCollections 无法完成的。

最大的区别在于KVC是用语言构建的。Obj-C 中的对象 NameValueCollection。您不必更改开发方式(从类和属性到字典(即可使用它。您可以使用所需的属性创建对象,然后调用 valueForKey:@"name",一切仍然有效。

现在你可以说:"是的,很酷,但我可以通过反思来做到这一点!当然可以,但就像以前一样,你必须再次改变你的发展方式,这还不包括反射通常要慢得多的事实。

KVC的另一个很酷的功能是它允许您使用KVO,这基本上允许您注册以接收有关任何对象更改的通知,而无需在这些对象中编写任何代码。因此,在应用程序中的任何对象中,都可以调用"addObserver:forKeyPath:",并在应用程序中的其他人更改该属性时接收回调。这对于实时应用程序(如iOS应用程序(非常有用。

同样,你可以在C#中实现KVO(例如MVVM框架一直这样做(,但你必须为此编写额外的代码。在 Obj-C 中,它是用语言构建的。

我在MonoMac的上下文中写了关于这个的博客,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");

在这种情况下,"position.x"引用图层的位置,在该位置内它是 X 分量。

上面的博客文章详细介绍了如何实际公开自己的对象以参与此协议(注册自己的属性以使它们对键值编码系统可见(。

Kenneth,另一位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> 来存储键/值对。在 C# 中不支持像 Objective-C 那样通过 KVC 自动访问属性。您可以将该属性声明为

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

但是,这不是很有效。