Cách tạo “mảng bộ chọn”


82

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

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

Tôi đã thử điều này, nhưng nó 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? Hay có cách nào tốt hơn để lặp lại qua một tập hợp các phương thức?

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

Câu trả lời:


79

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

Từ các tài liệu

NSSelectorFromString

Trả về bộ chọn với một tên đã cho.

SEL NSSelectorFromString (
   NSString *aSelectorName
);

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

1
NSPointerArraytốt hơn.
DawnSong

43

Điều này tạo ra một đối tượng ngoài bộ chọn:

[NSValue valueWithPointer:@selector(x)]

2
Bạn sẽ làm thế nào để giải nén bộ chọn từ cái này để được sử dụng performSelector:?
Dean Kelly

3
@DeanKelly trả lời ở đây stackoverflow.com/questions/575055/... bởi franguiadakis terry
ABCD.ca

1
SEL x = (SEL)selectorValue.pointerValue;
Nhập

35

Tại sao không chỉ 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 statickhông cần thiết ở đây (bộ khởi tạo không phải là hằng số thời gian biên dịch).
Aleks N.

12

Bạn cũng có thể tạo một mảng NSInvocations. Điều này rất hữu ích nếu bạn cần một đối số để đi với bộ chọn của mình.

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

NSInvocation quá đắt.
DawnSong

1

Nếu danh sách là tĩnh, tôi sẽ sử dụng giải pháp của KennyTM, nhưng nếu bạn cần một mảng động hoặc tập hợp, thì một tùy chọn khác, ngoài việc lưu trữ chuỗi bộ chọn, là tạo một đối tượng có thuộc SELtính 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ũng có thể thêm một performphương thức vào lớp và thực hiện lời gọi phương thức ở đó.


1

Tôi muốn bổ sung hai phương pháp lưu trữ bộ chọn trong một mảng,

Đầu tiên, NSPointerArraycó thể lưu trữ con trỏ mờ, chẳng hạn như SEL, như tài liệu của Apple đã nói,

NSPointerArray *selectors = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsOpaqueMemory];
[selectors addPointer:@selector(onSendButton:)];
[button addTarget: self action:[selectors pointerAt:0] forControlEvents:UIControlEventTouchUpInside];

Thứ hai, mảng kiểu C đơn giản hơn nhiều,

SEL selectors[] = { @selector(onSendButton:) };
[button addTarget: self action:selectors[0] forControlEvents:UIControlEventTouchUpInside];

Chọn bất kỳ như bạn muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.