2010-02-09 26 views
80

Tôi đang sử dụng SDK iPhone (3.0) và tôi đang cố gắng tạo một mảng chọn lọc để gọi nhiều phương thức khác nhau trong một lớp.cách tạo "mảng bộ chọn"

Rõ ràng, tôi đang làm điều gì đó sai (tôi nghĩ @selector không được coi là một lớp và do đó nhồi chúng vào một NSArray không hoạt động).

Tôi đã thử điều này, nhưng rõ ràng là sai.

Có cách nào đơn giản để có một mảng bộ chọn như thế này không? Hoặc là có một cách tốt hơn để lặp qua một bộ sưu tập các phương pháp?

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; 
} 

Trả lời

79

Bạn có thể lưu trữ chuỗi và sử dụng NSSelectorFromString không?

Từ docs

NSSelectorFromString 

Trả về selector với một tên nhất định.

SEL NSSelectorFromString (
    NSString *aSelectorName 
); 
+0

nghe hay với tôi. cám ơn! – user141146

+0

Không phải là giải pháp thích hợp khi chỉ cần một mảng các bộ chọn. –

40

Điều này tạo ra một đối tượng ra khỏi selector:

[NSValue valueWithPointer:@selector(x)] 
+2

Làm thế nào bạn sẽ đi về giải nén bộ chọn từ này để được sử dụng bởi 'performSelector:'? –

+3

@DeanKelly đã trả lời tại đây http://stackoverflow.com/questions/575055/how-to-build-a-nsarray-or-nsmutablearray-of-class-methods-in-objective-c bởi terry franguiadakis –

+0

Loại diễn viên là cần thiết , như sau, 'SEL x = (SEL) selectorValue.pointerValue;' –

34

Tại sao không chỉ cần sử dụng một mảng C đơn giản?

static const SEL selectors[] = {@selector(method1), 
           .... 
           @selector(method7)}; 

... 

for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) { 
    [self performSelector:selectors[i]]; 
    // .... 
} 
+3

Tốt, nhưng 'tĩnh' là không cần thiết ở đây (initializer không phải là một hằng số biên dịch-thời gian). –

+0

câu trả lời này cần thêm phiếu bầu! –

12

Bạn cũng có thể tạo mảng NSInvocation s. Điều này rất tiện lợi nếu bạn cần một đối số để đi với bộ chọn của bạn.

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 
+0

NSInvocation quá đắt. –

1

Nếu danh sách là tĩnh, tôi muốn đi với giải pháp KennyTM, nhưng nếu bạn cần một mảng động hoặc thiết lập, tùy chọn khác, bên cạnh việc lưu trữ các chuỗi selector, là để tạo ra một đối tượng với một tài sản SEL hoặc ivar, và lưu trữ đó.

@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 

Sau đó bạn có thể thêm phương thức perform vào lớp học và thực hiện cuộc gọi phương thức tại đó.

Các vấn đề liên quan