Khai báo một tham số phương thức khối mà không sử dụng typedef


146

Có thể chỉ định tham số khối phương thức trong Objective-C mà không cần sử dụng typedef không? Nó phải giống như các con trỏ hàm, nhưng tôi không thể nhấn vào cú pháp chiến thắng mà không sử dụng một typedef trung gian:

typedef BOOL (^PredicateBlock_t)(int);
- (void) myMethodTakingPredicate:(PredicateBlock_t)predicate

chỉ các biên dịch trên, tất cả đều thất bại:

-  (void) myMethodTakingPredicate:( BOOL(^block)(int) ) predicate
-  (void) myMethodTakingPredicate:BOOL (^predicate)(int)

và tôi không thể nhớ những kết hợp khác mà tôi đã thử.


Câu trả lời:


238
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( int ) )predicate

9
+1, mặc dù typedefthực sự nên được ưu tiên cho các trường hợp phức tạp hơn.
Fred Foo

3
- ( void )myMethodTakingPredicate: ( BOOL ( ^ )( NSString *name, NSString *age ) )predicate { //How Should I Access name & age here...? }
Mohammad Abdurraafay

6
Đó chỉ là tên tham số. Chỉ cần sử dụng chúng.
Maccraft

1
@larsmans Tôi đồng ý, trừ khi vị từ / khối đặc biệt này được sử dụng ở nhiều nơi, nơi nó sẽ rõ ràng hơn nếu có nó typedef'd. Apple đã định nghĩa một số khối khá đơn giản, nhưng đã làm như vậy để dễ dàng tìm thấy những gì họ muốn trong tài liệu.
mtmurdock

2
Khuyến nghị mạnh mẽ! Đặt tên cho các biến của bạn. Họ sẽ tự động hoàn thành mã có thể sử dụng. Vì vậy, thay thế BOOL ( ^ )( int )bằng BOOL ( ^ )( int count ).
funroll

65

Đây là cách nó diễn ra, ví dụ ...

[self smartBlocks:@"Pen" youSmart:^(NSString *response) {
        NSLog(@"Response:%@", response);
    }];


- (void)smartBlocks:(NSString *)yo youSmart:(void (^) (NSString *response))handler {
    if ([yo compare:@"Pen"] == NSOrderedSame) {
        handler(@"Ink");
    }
    if ([yo compare:@"Pencil"] == NSOrderedSame) {
        handler(@"led");
    }
}

Có lý do nào bạn không sử dụng phương thức [NSString isEqualToString:] không?
orkoden

2
Không có gì cụ thể. Tôi chỉ sử dụng để sử dụng 'so sánh:' rất nhiều. '[NSString isEqualToString:]' là cách tốt hơn.
Mohammad Abdurraafay

Bạn có cần từ responsetrong smartBlocksđịnh nghĩa phương thức không? Bạn không thể nói (NSString*))handler {sao?
Tro

Bạn có thể có (NSString *)) handler. Điều đó cũng hợp lệ.
Mohammad Abdurraafay


9

Một ví dụ khác (vấn đề này được hưởng lợi từ nhiều):

@implementation CallbackAsyncClass {
void (^_loginCallback) (NSDictionary *response);
}
// …


- (void)loginWithCallback:(void (^) (NSDictionary *response))handler {
    // Do something async / call URL
    _loginCallback = Block_copy(handler);
    // response will come to the following method (how is left to the reader) …
}

- (void)parseLoginResponse {
    // Receive and parse response, then make callback

   _loginCallback(response);
   Block_release(_loginCallback);
   _loginCallback = nil;
}


// this is how we make the call:
[instanceOfCallbackAsyncClass loginWithCallback:^(NSDictionary *response) {
   // respond to result
}];

2

Thậm chí rõ ràng hơn!

[self sumOfX:5 withY:6 willGiveYou:^(NSInteger sum) {
    NSLog(@"Sum would be %d", sum);
}];

- (void) sumOfX:(NSInteger)x withY:(NSInteger)y willGiveYou:(void (^) (NSInteger sum)) handler {
    handler((x + y));
}
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.