同じインターフェイスで別のオブジェクトをラップするObjective -Cオブジェクトを作成する-KVC/KVOの問題
-
01-10-2019 - |
質問
別のオブジェクトからオブジェクトを包むオブジェクトを1つのクラスの階層に作成する必要があります。どちらも非常によく似たインターフェイスを持っています。独自のプロパティを実装する代わりに、ターゲットに認識していないラッパーのフォワードメッセージを自動的に持ちたいと思います。私はこれをこのようなものを使って動作させました:
- (id)forwardingTargetForSelector:(SEL)sel { if ([self.wrappedObject respondsToSelector:sel]) return self.wrappedObject; return self; }
しかし、これはキー価値コーディングでは機能しません。ラッパーに、ラップされたオブジェクトのプロパティを使用する方法でキー価値コーディングを実装するにはどうすればよいですか?
解決
上書きする必要があります valueForKey:
と setValue:forKey:
. 。例:
- (id)valueForKey:(NSString *)key {
if (/* wrapped object has key */)
return [self.wrappedObject valueForKey: key];
else
return [super valueForKey: key];
}
トリッキーな部分は、ラップオブジェクトが実装するキーを決定することです。簡単な方法はそれらをハードコードすることですが、それはあまり良くありません。非常に一般的なことをしたい場合は、Objective-Cの反射APIを使用して何かをします。ここに2つのアイデアがあります:
すべてのプロパティは、実際には宣言されたプロパティです。 Runtime Function Class_GetPropertyを使用して、その存在を確認し、オプションで追加情報を抽出できます。チェックは次のようになります。
if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}
.あなたのプロパティにはアクセサのみが含まれている可能性があります。 次に、キーからセレクターを構築して使用する必要があります
[self.wrappedObject respondsToSelector: ...]
あなたが以前と同じように。ゲッターの名前はキーとコロンです。ただし、これの問題は、ゲッター/セッター名が異なるプロパティです。最初のオプションは間違いなく最高です。