私はiPhone SDK(3.0)を使用しており、1つのクラス内でさまざまなメソッドを呼び出すためにセレクターの配列を作成しようとしています。
明らかに、私は何か間違ったことをしています(@selectorはクラスと見なされないため、NSArrayに詰め込むことは機能しません)。
私はこれを試しましたが、明らかに間違っています。
このようなセレクターの配列を持つ簡単な方法はありますか?またはメソッドのコレクションを反復処理するより良い方法はありますか?
selectors = [NSArray arrayWithObjects:
@selector(method1),
@selector(method2),
@selector(method3),
@selector(method4),
@selector(method5),
@selector(method6),
@selector(method7), nil];
for (int i = 0; i < [selectors count]; i++) {
if ([self performSelector:[selectors objectAtIndex:i]]) // do stuff;
}
文字列を保存してNSSelectorFromStringを使用できますか?
docs から
NSSelectorFromString
指定された名前のセレクターを返します。
SEL NSSelectorFromString (
NSString *aSelectorName
);
これにより、セレクターからオブジェクトが作成されます。
[NSValue valueWithPointer:@selector(x)]
単純なC配列を使用しないのはなぜですか?
static const SEL selectors[] = {@selector(method1),
....
@selector(method7)};
...
for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
[self performSelector:selectors[i]];
// ....
}
NSInvocation
sの配列を作成することもできます。これは、セレクタを使用するために引数が必要な場合に便利です。
NSMethodSignature *sig = [[yourTarget class] instanceMethodSignatureForSelector:yourSEL];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
[inv setTarget:yourTarget];
[inv setSelector:yourSEL];
[inv setArgument:&yourObject atIndex:2]; // Address of your object
セレクターを配列に格納する2つの方法を補完したいと思います。
まず、NSPointerArray
はSEL
などの不透明なポインターを保存できます。 Apple doc
NSPointerArray *selectors = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsOpaqueMemory];
[selectors addPointer:@selector(onSendButton:)];
[button addTarget: self action:[selectors pointerAt:0] forControlEvents:UIControlEventTouchUpInside];
第二に、Cスタイルの配列ははるかに単純です。
SEL selectors[] = { @selector(onSendButton:) };
[button addTarget: self action:selectors[0] forControlEvents:UIControlEventTouchUpInside];
必要に応じていずれかを選択します。
リストが静的な場合は、KennyTMのソリューションを使用しますが、動的な配列またはセットが必要な場合は、セレクター文字列を保存する以外に、SEL
プロパティまたはivarを持つオブジェクトを作成します。それを保存します。
@interface SelectorObject : NSObject
@property (assign, readonly, nonatomic) SEL selector;
- (id)initWithSelector:(SEL)selector;
@end
@implementation SelectorObject
- (id)initWithSelector:(SEL)selector {
self = [super init];
if (self) {
_selector = selector;
}
return self;
}
@end
次にperform
メソッドをクラスに追加し、そこにメソッド呼び出しを実装します。