7

Monotouch による iOS 開発に切り替える前に、ObjectiveC を少しいじりました。それ以来、「キーバリューコーディング」(KVC)ということが頭に浮かびました。それが何に役立つのか、その背後にある魔法が何であるかを理解したことがありません.

私の理解では、.NET のような名前と値の単なるコレクションです。設定するNameValueCollection代わりに、. 偉大な。だから何?これは私には簡単すぎるように見えるので、そうではないはずです。anObject.Address = "An address Value"anObject.Properties["Address"] = "An address value"

それとも、.NET にはリフレクションがあるため、Key-Value-Coding などは必要ないのでしょうか? " " の型を取得し、anObjectリフレクションを使用してそのすべてのプロパティをループし、"Address" という名前のプロパティを探してから、リフレクションを使用して値を設定します。それはおそらくKVCの類推ですか?

ObjC と C#/.NET のプロで、その利点と、それが .NET にどのように変換されるかを説明してくれる人がいることを願っています。Apple のドキュメントだけを指ささないでください。私はそれをすべて知っています。KVC を知らないことで、これまでのコーディング ライフに何か欠けているものがあるかどうかを調べようとしています。または、ObjC を使用している場合に KVC に変換されることを認識せずに、.NET で同様のものを使用していたのでしょうか?

4

3 に答える 3

11

おそらく3年間、両方を毎日使用している誰かから:

おわかりのように、KVC には驚くほど複雑で、C# の辞書と NameValueCollection で実行できないものはありません。

大きな違いは、KVC が言語に組み込まれていることです。Obj-C のオブジェクトはNameValueCollectionです。それを使用するために (クラスやプロパティから辞書まで) 開発方法を変更する必要はありません。必要なプロパティを使用してオブジェクトを作成し、後で valueForKey:@"name" を呼び出しても、すべてが機能します。

これで、「ええ、クールですが、リフレクションでそれを行うことができます!」と言うことができます。確かにできますが、以前と同じように、リフレクションが一般的にはるかに遅いという事実を考慮せずに、開発方法を再度変更する必要があります.

KVC のもう 1 つの優れた機能は、KVO を使用できることです。これにより、基本的に、オブジェクトにコードを 1 行も書かなくても、登録してオブジェクトの変更に関する通知を受け取ることができます。したがって、アプリケーション内の任意のオブジェクトで、「addObserver:forKeyPath:」を呼び出すことができ、アプリケーション内の他の誰かがそのプロパティを変更した場合にコールバックを受け取ることができます。これは、iOS アプリなどのライブ アプリに非常に役立ちます。

繰り返しになりますが、C# で KVO を実装できます (たとえば、MVVM フレームワークでは常にこれが行われます) が、そのためには追加のコードを記述する必要があります。Obj-C では、言語に組み込まれています。

于 2012-02-25T23:18:52.623 に答える
7

これについては、MonoTouch のピア プロジェクトであるが Mac アプリケーションの構築に使用される MonoMac のコンテキストでブログを書きました。

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

Key-Value コーディングは、アプリケーションが文字列を使用してオブジェクト プロパティにアクセスできるようにする一連のプラクティスです。これは、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 システムに表示できるようにする) について詳しく説明しています。

もう 1 人の MonoMac 開発者の 1 人である Kenneth は、こ​​れについて広範囲にわたってブログに書いています。

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

特に、彼は Reflection との類似点を扱い、[Export] を使用して C# コードを KVC 準拠のコードに変換する方法も示しています。

于 2012-02-26T17:47:21.520 に答える
4

このようなプロパティにアクセスすると

anObject.Address = "An address Value"

コードは非常に「静的」になります。必ずアクセスしますAddress

このようなより動的なコードを作成できます

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

コンパイル時にアクセスされるプロパティがわからない場合は、これを行います。

C# では、通常、Dictionary<TKey,TValue>キーと値のペアを格納するために a を使用します。Objective-C のように KVC を介してプロパティに自動的にアクセスすることは、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);

ただし、これはあまり効率的ではありません。

于 2012-02-25T21:29:39.863 に答える