传递与签名不匹配的块参数

chi*_*fet 8 objective-c objective-c-blocks

我正在使用基于块的API,偶然发现了一个场景,我传递的块参数的签名与方法所期望的typedef'd参数不匹配.令我惊讶的是,编译器似乎并不关心这一点,并且应用程序没有崩溃.这是预期的行为吗?例:

typedef void(^MyBlock)();
typedef void(^MyBlockWithParam)(id param);

- (void)doWork {
    MyBlockWithParam block1 = ^(id param) {
        NSLog(@"block1: %@", param);
    };

    MyBlock block2 = ^{
        NSLog(@"block2");
    };

    [self loadData:block1];
    [self loadData:block2];
}

- (void)loadData:(MyBlockWithParam)block {
    block(@"foo");
}
Run Code Online (Sandbox Code Playgroud)

nie*_*bot 9

提供一个空的参数规范,如

typedef void(^MyBlock)();
Run Code Online (Sandbox Code Playgroud)

意思是"未指明"的论点.所以这两种类型是兼容的.将第一个声明更改为

typedef void(^MyBlock)(void);
Run Code Online (Sandbox Code Playgroud)

指定该块不带参数,您将收到错误.

K&R C指定空参数列表表示"未指定".C块规范说对于块类型声明不是这样(参见http://clang.llvm.org/docs/BlockLanguageSpec.html#block-variable-declarations)但是:GCC和Clang都将K&R行为实现为语言扩展.