Objective C块声明冲突

Ale*_* N. 1 iphone typedef objective-c objective-c-blocks

关于目标c块,我遇到了一些非常烦人的问题.比方说,我们有这样的代码:

//Class1.h
#import <Foundation/Foundation.h>

typedef void (^Class1Callback)(BOOL bl);

@interface Class1 : NSObject { }

- (id)initWithCallback:(Class1Callback)callback;

@end

//Class2.h
#import <Foundation/Foundation.h>

typedef enum Class2Enum { Foo, Bar, FooBar } Class2Enum;

typedef void (^Class2Callback)(Class2Enum ce);

@interface Class2 : NSObject { }

- (id)initWithCallback:(Class2Callback)callback;

@end

//main.c
#import "Class1.h"
#import "Class2.h"

int main(int argc, char *argv[]) {
    Class1 *class1 = [[Class1 alloc] initWithCallback:^(BOOL bl){ }];
    Class2 *class2 = [[Class2 alloc] initWithCallback:^(Class2Enum ce){ }];
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中我得到一个错误"不兼容的块指针类型初始化'void(^)(枚举Class2Enum)',期望'Class1Callback'"在行

Class2 *class2 = [[Class2 alloc] initWithCallback:^(Class2Enum ce){ }];
Run Code Online (Sandbox Code Playgroud)

但是当我在main.c中反向导入时,即

#import "Class2.h"
#import "Class1.h"
Run Code Online (Sandbox Code Playgroud)

错误改变了它的位置和描述 - 现在它符合要求

Class1 *class1 = [[Class1 alloc] initWithCallback:^(BOOL bl){ }];
Run Code Online (Sandbox Code Playgroud)

和描述是"不兼容的块指针类型初始化'void(^)(BOOL)',期望'Class2Callback'"

当方法的声明表明块类型是Class1Callback时,为什么编译器期望'Class2Callback'?我不知道为什么会发生这种情况,我应该寻求什么以及我应该阅读什么以找到答案.有什么建议?

Jon*_*pan 7

+alloc返回一个id,这是Objective-C中的通用对象类型.因此,编译器不知道-initWithCallback:你的意思,因为id理论上它可以是你的任何一个类的实例.您必须将+alloc调用的结果强制转换为您正在实例化的类,如下所示:

Class1 *class1 = [(Class1 *)[Class1 alloc] initWithCallback: ...];
Run Code Online (Sandbox Code Playgroud)

或者,重命名初始化方法,使它们不相同,编译器将能够区分它们.如果可以,请尝试更具描述性的内容:

- (id)initWithCompletionHandler: (Class1Callback)handler;
- (id)initWithProgressHandler: (Class2Callback)handler;
Run Code Online (Sandbox Code Playgroud)