Objective-C:如何将对象作为块参数传递给期望其基类的方法?

7
如果我有以下对象:
@interface Simple : NSObject

@end

@interface Complex : Simple

@end

还有另一个类似的对象:

@interface Test : NSObject 

+(void) doSomething:(void (^)(Simple*)) obj;

@end

如果我这样调用方法,一切都可以正常运行:

[Test doSomething:^(Simple * obj) {

}];

当我尝试这样调用它时:

[Test doSomething:^(Complex * obj) {

}];

编译器报错如下:

不兼容的块指针类型,将'void (^)(Complex *__strong)'发送到类型为'void (^)(Simple *__strong)'的参数

由于Complex扩展了Simple,我认为这应该像Java一样工作。

有什么方法可以解决这个问题吗?

2个回答

8

很遗憾,这是Blocks API的限制。如果您愿意,可以完全放弃类型安全,并将块声明为:

+(void) doSomething:(void (^)(id)) obj;

这允许您设置代码块参数的类。但是需要注意,这种方式完全不安全,可能导致类型错误。


这真的很不幸吗?Test 请求并获得一个带有签名的块的引用,该签名表示该块需要一个类型为Simple的参数。传递一个接受子类型Complex的块可能意味着Test通过调用具有不同Simple子类的块来进行非法调用。 - Seamus Campbell
我只是在说,把这个叫做违约似乎是合理的。如果不是这样,编译器就无法知道Test中任何调用执行该块的参数是否合法。 - Seamus Campbell
@SeamusCampbell 对不起,我没有完全阅读你写的内容。是的,没错。 - CodaFi

2

使用 id 代替 Complex * 或者 Simple *。块参数类型和方法参数类型的处理方式不同(感谢 @CodaFi)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接