2

1 つの UIViewController に使用する dataSource がいくつかあります。私のView Controllerは、実行時に特定のプロパティの状態を追跡するためにKeyValue Observingを使用しています。dataSource を交換するときは、それらのプロパティの監視を停止する必要があります。問題は、実行時の dataSource のクラスがわからないため、次のようなものは無効です。

if (aDataSource != dataSource) {
    // Ensure we stop observing the existing dataSource, otherwise bad stuff can happen.
    [dataSource removeObserver:self forKeyPath:@"someKeyPath"]; // not valid, compiler doesn't know what class dataSource is.
    [dataSource release];
    dataSource = [aDataSource retain];
}

コンパイラは、オブジェクトのインターフェイスを知るために具象クラスを必要とします。この特定のケースで dataSource のクラスを取得してから、上記の removeObserver:forKeyPath: セレクターの dataSource を typcast するにはどうすればよいですか? クラスの名前を NSString インスタンスにキャッシュし、切り替えるたびにそれを参照するよりも、動的でスマートなものを好みます。つまり、私はいつでも次のようなことができます:

NSString *lastDataSource = @"MyClass";
Class foo = [NSClassFromString(lastDataSource)];

ありがとう。

4

4 に答える 4

6
  1. 次のようにコーディングする場合:

    id foo = ...;
    [foo removeObserver:self forKeyPath:@"someKeyPath"];
    

    type を持つオブジェクトidは任意のメッセージを受け入れるため、コンパイラはそれで問題ありません (署名がコンパイラに知られている限り)。

  2. あなたが持っている場合:

    id<NSObject> foo = ...;
    [foo removeObserver:self forKeyPath:@"someKeyPath"];
    

    コンパイラは警告を表示します:

    警告: '-removeObserver:forKeyPath:' がプロトコルに見つかりません

    これは、KVO メソッドが定義されている NSObject クラスではなく、プロトコル NSObject を参照しているためです。

  3. ただし、次の場合:

    NSObject* foo = ...;
    [foo removeObserver:self forKeyPath:@"someKeyPath"];
    

    この場合はクラス NSObject を使用しているため、これも問題なくコンパイルされます。

関連リンク:

于 2009-05-22T18:21:44.473 に答える
2

有効ではないということは何ですか?コンパイルエラーになりますか?

Objective-C は、デフォルトでオブジェクトの動的型付けをサポートしています。オブジェクトがそのメソッドをサポートしていることをコンパイラが静的型から保証できない場合でも、Objective-C の任意のオブジェクトで任意のメソッドを呼び出すことができるはずです。

于 2009-05-22T17:49:05.697 に答える
1

あなたが概説したアプローチを追加させてください...

NSString *lastDataSource = @"MyClass";
Class foo = [NSClassFromString(lastDataSource)];

...クラス「foo」は実行時にのみ計算されるため、もちろんコンパイル時の警告を抑制することはできません。したがって、プログラマーとしてコードから「foo」が最終的にクラス「MyClass」になることが明白にわかりますが、これはコンパイラーには明らかではありません。したがって、「MyClass」にメソッド「myMethod:」がある場合は、そのメッセージを「foo」として宣言されたオブジェクトに送信すると、コンパイラの警告が表示されます。

あなたはこれを理解していると思いますが、なぜそのアプローチがあなたの問題を解決しないのかを明確にする方が良いでしょう.

于 2009-05-24T10:17:45.973 に答える
1

にキャストする必要があると思いますNSObject *.KVOメソッドがある場所だからです(NSObjectプロトコルではありません)。

于 2009-05-22T18:10:48.483 に答える