ประกาศพารามิเตอร์เมธอดบล็อกโดยไม่ใช้ typedef


146

เป็นไปได้ที่จะระบุพารามิเตอร์ method block ใน Objective-C โดยไม่ต้องใช้ typedef หรือไม่? จะต้องเป็นเช่นตัวชี้ฟังก์ชั่น แต่ฉันไม่สามารถเข้าถึงไวยากรณ์ที่ชนะโดยไม่ต้องใช้ตัวพิมพ์กลาง:

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

เฉพาะการคอมไพล์ด้านบนสิ่งเหล่านี้ล้มเหลว:

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

และฉันจำไม่ได้ว่าชุดค่าผสมอื่น ๆ ที่ฉันได้ลองไว้


คำตอบ:


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

9
+1, แม้ว่าtypedefควรจะเป็นที่ต้องการจริงๆสำหรับกรณีที่ซับซ้อนมากขึ้น
Fred Foo

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

6
นี่เป็นเพียงชื่อพารามิเตอร์ เพียงแค่ใช้พวกเขา
Macmade

1
@ larsmans ฉันเห็นด้วยเว้นแต่ว่าคำกริยา / บล็อกนี้ถูกใช้ในหลาย ๆ ที่ที่มันชัดเจนกว่าที่จะพิมพ์ลงไป Apple ได้กำหนดจำนวนบล็อกที่ค่อนข้างง่าย แต่ทำเช่นนั้นเพื่อให้ง่ายต่อการค้นหาสิ่งที่พวกเขาต้องการในเอกสาร
mtmurdock

2
คำแนะนำที่แข็งแกร่ง! ตั้งชื่อตัวแปรของคุณ พวกเขาจะเติมข้อความอัตโนมัติในรหัสที่ใช้งานได้ ดังนั้นแทนที่ด้วยBOOL ( ^ )( int ) BOOL ( ^ )( int count )
funroll

65

นี่คือวิธีที่จะไปเช่น ...

[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");
    }
}

มีเหตุผลที่คุณไม่ใช้วิธี [NSString isEqualToString:] หรือไม่
orkoden

2
ไม่มีอะไรพิเศษ ฉันแค่ใช้เพื่อ 'เปรียบเทียบ:' มาก '[NSString isEqualToString:]' เป็นวิธีที่ดีกว่า
Mohammad Abdurraafay

คุณต้องการคำresponseในsmartBlocksนิยามวิธีการหรือไม่? คุณพูด(NSString*))handler {ไม่ได้เหรอ
เถ้า

(NSString *)) handlerคุณอาจจะมี นั่นก็ใช้ได้เช่นกัน
Mohammad Abdurraafay


9

ตัวอย่างอื่น (ปัญหานี้ได้รับประโยชน์จากหลายรายการ):

@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

ชัดเจนยิ่งขึ้น!

[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));
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.