Objective C块声明冲突

时间:2011-01-17 16:21:59

标签: iphone objective-c typedef 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){ }];
}

在这段代码中,我收到错误“不兼容的块指针类型初始化'void(^)(枚举Class2Enum)',预期'Class1Callback'”行

Class2 *class2 = [[Class2 alloc] initWithCallback:^(Class2Enum ce){ }];

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

#import "Class2.h"
#import "Class1.h"

错误改变了它的位置和描述 - 现在它在行

Class1 *class1 = [[Class1 alloc] initWithCallback:^(BOOL bl){ }];

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

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

1 个答案:

答案 0 :(得分:7)

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

Class1 *class1 = [(Class1 *)[Class1 alloc] initWithCallback: ...];

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

- (id)initWithCompletionHandler: (Class1Callback)handler;
- (id)initWithProgressHandler: (Class2Callback)handler;