さて、これが私が見つけた解決策です...何をすべきかがわかれば、非常に簡単になりました。最初に「- (id) forwardingTargetForSelector:(SEL)aSelector」を上書きし、iVar を返します。
- (id) forwardingTargetForSelector:(SEL)aSelector{
return iVar;
}
ランタイムがメソッドを探しているときに見つからない場合、このメソッドを呼び出して、メッセージを転送する別のオブジェクトがあるかどうかを確認します。通常、このメソッドは nil を返します。ここで nil を返すと、プログラムがクラッシュすることに注意してください (これは適切な動作です)。
問題の 2 番目の部分は、宣言されていないメッセージを送信しようとしたときに表示されるコンパイラ エラー/警告をシャットアウトすることです。これは、実装しないカテゴリを宣言することで簡単に実行できます。
@interface Class (iVarClassMethods)
@propoperty (strong) Class *property1;
......more properties
@end
どこにも実装を入れない限り、別名@implementation Class (category)
、コンパイラは文句を言いません(実装がどこかにあると想定します....)。
唯一の欠点は、iVar クラスのインターフェイスのプロパティを変更した場合、上記の方法を使用する他のすべてのクラスを更新する必要があることです。そうしないと、別のクラスが送信しようとしたときにクラッシュします。間違った方法は何ですか (コンパイラは事前に警告しません)。ただし、これは回避できます。カテゴリでプロトコルを宣言できます。代わりに、iVar クラス用に別のプロトコルを作成し、必要なメソッド/プロパティを iVar クラスからプロトコルに移動します。
@protocol iVarClassProtocol
@propoperty (strong) Class *property1;
......more properties
@end
そのプロトコルを iVar サブクラスに追加して、これらのメソッドがプロトコルを通じて宣言されるようにします。
@interface iVarClass <iVarClassProtocol>
....other methods/properties you don't need forwarded
@end
最後に、プロトコルをカテゴリに追加するだけです。したがって、明示的な宣言を持つ前述のカテゴリの代わりに、次のようになります。
@interface Class (iVarClassMethods) <iVarClassProtocol>
@end
ここで、転送するプロパティ/メソッドのいずれかを変更する必要がある場合は、プロトコルでそれらを変更します。間違ったメソッドを転送クラスに送信しようとすると、コンパイラは警告を発します。