配列内のすべてのオブジェクトにセレクターを実行させたいです。makeObjectsPerformSelector:
適切な名前のメソッドを発見しましたが、それについて質問があります。配列で使用すると、既存の配列が変更されるか、新しい配列が返されますか? 既存のオブジェクトを変更する場合、セレクターが適用された新しい配列を返す最も簡単な方法は何ですか?
5 に答える
makeObjectsPerformSelector: は、配列内のすべてのオブジェクトに対してそのセレクターを実行します。それらのオブジェクトがセレクターによって変更された場合、それらは変更されます。何も返しません。ここで、デフォルトでは Cocoa のほとんどのコピーが浅いコピーであるという問題があります。これは、新しい配列を取得することを意味しますが、それが指す基になるオブジェクトは同じオブジェクトです。ルート レベルのアイテムもコピーするには、initWithArray:copyItems を使用する必要があります。変更されたオブジェクトと古い配列を含む新しい配列が必要な場合は、次のようにします。
NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];
配列で使用すると、既存の配列が変更されるか、新しい配列が返されますか?
いいえ。
まず、署名を読んでください。
- (void)makeObjectsPerformSelector:(SEL)aSelector
void
の後に星がない場合は、「何も返さない」ことを意味します。
次に、これは不変クラスである NSArray のメソッドであることに注意してください。したがって、それmakeObjectsPerformSelector:
は不可能なので、受信配列を変更しません。
NSMutableArray があり、それは NSArray のサブクラスであるため、 を継承していmakeObjectsPerformSelector:
ます。ただし、NSMutableArray がそのメソッドの動作を変更した場合、そのドキュメントにはメソッドの独自のリストが含まれます (init
さまざまなクラスのドキュメントにある の多くの定義を参照してください)。-[NSMutableArray makeObjectsPerformSelector:]
そのようなリストはないので、 とまったく同じように動作することを安全に (そして正しく) 推測できます-[NSArray makeObjectsPerformSelector:]
。
オブジェクトはメッセージに応じて自身を変更できますが、配列自体にはmakeObjectsPerformSelector:
前と同じオブジェクトが含まれます。
他の回答に加えて、メソッドを呼び出した結果で新しい配列を作成したい場合は、これを行うことができます:
NSArray *derivedArray = [originalArray valueForKey:@"foo"];
これは、オブジェクトが「-valueForKey:@"foo"」メッセージを処理できる場合にのみ機能し、明らかに、引数を取らず、非 nil 値を返すメソッドにのみ適しています。
私はこれを正しく解釈していることを願っています...
[myArray makeObjectsPerformSelector:someSelector] を実行すると、事実上、myArray を反復処理してセレクタ メッセージを各オブジェクトに送信するだけです。makeObjectsPerformSelector はその内容を変更できないため、配列は変更されません。
したがって、最終的には、同じオブジェクトを持つ同じ配列が得られます。