Вызов встроенного блока с указанием типа и параметров возврата - PullRequest
3 голосов
/ 01 сентября 2011

Я решил попробовать использовать блоки для управления потоком в Objective-C и столкнулся с некоторыми проблемами при вызове нескольких блоков в линию.

У меня есть OOBoolean, который является оболочкой для примитива BOOL и предоставляет следующие методы:

+ (id) booleanWithBool: (BOOL) boolPrimitive;

- (id) initWithBool: (BOOL) boolPrimitive;

- (void) ifTrueDo: (void (^) ()) trueBlock 
        ifFalseDo: (void (^) ()) falseBlock;

- (void) ifTrueDo: (void (^) ()) trueBlock;

- (void) ifFalseDo: (void (^) ()) falseBlock;

У меня нет проблем с использованием этого класса, вот так:

OOBoolean* condition = [OOBoolean booleanWithBool: (1 + 1 == 2)];

id trueBlock = ^(){
    NSLog(@"True.");
};

id falseBlock = ^(){
    NSLog(@"False.");
};

[condition ifTrueDo: trueBlock ifFalseDo: falseBlock];

И я получаю результат «Правда». Но я продолжаю получать синтаксические ошибки при попытке это вместо:

OOBoolean* condition = [OOBoolean booleanWithBool: (1 + 1 == 2)];

[condition ifTrueDo:(void (^)()) {
    NSLog(@"True");
} ifFalseDo:(void (^)()) {
    NSLog(@"False");
}];

Разве невозможно определить несколько блоков анонимно и передать их методу, который принимает несколько аргументов блока? Если так, то это своего рода разочарование.

Ответы [ 2 ]

7 голосов
/ 01 сентября 2011

Это возможно.

У вас там было слишком много скобок. Попробуйте это:

[condition ifTrueDo:^() { NSLog(@"True"); } ifFalseDo:^() { NSLog(@"False"); } ];

EDIT: Ваш синтаксис блока немного неправильный.

Если вы хотите включить тип возвращаемого значения и параметры, вы должны использовать что-то ближе к этому:

[self ifTrueDo:^ void (void) { NSLog(@"True"); } ifFalseDo:^ void (void) { NSLog(@"False"); } ];

На английском:

^ [return type] ([parameter list]) {[block content]}

1 голос
/ 01 сентября 2011

Проблема в том, что объявление вашего метода ожидает блок, возвращающий void (ничто):

- (void) ifTrueDo: (void (^) ()) trueBlock 
        ifFalseDo: (void (^) ()) falseBlock;

Однако позже вы вызываете эту передачу в блоках с подписью (id ^ () ()):

[condition ifTrueDo:(id (^)()) {
    NSLog(@"True");
}         ifFalseDo:(id (^)()) {
    NSLog(@"False");
}];

Просто избавьтесь от части "id", как показано ниже - примечание: и я попробовал это, и он компилируется без предупреждений:

[condition ifTrueDo:^{
          NSLog(@"True");
     }
     ifFalseDo:^{
          NSLog(@"False");
     }
 ];
...