【发布时间】:2021-01-04 11:36:58
【问题描述】:
“Xcode 12.0 (12A7209)”在以下代码中显示针对 Cocos3D 库(用 Objective-C 编写)的编译错误:
(Xcode的过去版本((即ver.11, 10),包括ver 11.7(11801a))没有这个问题,但Xcode 12.0有。)
错误信息:
不兼容的块指针类型将“void (^)(CC3ShaderProgram *, BOOL *)”发送到“void (^)(id, BOOL *)”类型的参数
// CC3Shaders.m
+(void) willBeginDrawingScene {
[_programCache enumerateObjectsUsingBlock: ^(CC3ShaderProgram* prog, BOOL* stop) {
[prog willBeginDrawingScene];
}];
}
// CC3Cache.m
-(void) enumerateObjectsUsingBlock: (void (^) (id<CC3Cacheable> obj, BOOL* stop)) block {
[self lock];
[_objectsByName enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL* stop) {
block([obj resolveWeakReference], stop);
}];
[self unlock];
}
基本上 Xcode 12.0 的 ObjC 编译器会抱怨块“enumerateObjectsUsingBlock:”的输入参数的对象类型不匹配。
但是“CC3ShaderProgram”继承自“NSObject with CC3Cacheable protocol”如下:
@interface CC3ShaderProgram : CC3Identifiable
@interface CC3Identifiable : NSObject <CC3Cacheable, NSCopying>
因此,“CC3ShaderProgram”是与“id”匹配的类型,因此编译器不应抱怨,但 Xcode12.0 会抱怨。
不仅在“willBeginDrawingScene”,而且在库中使用“enumerateObjectsUsingBlock:”的其他地方也有同样的问题。
过去几年我一直在使用 Cocos3D 库和几个不同版本的 Xcode,没有这个问题。
在“Xcode 12.0”的 CLANG 或 SDK 中是否进行了任何更改以在块参数类型检查方面变得更加严格(例如“不允许使用通用对象指针“id”)?否则,我不明白为什么这两种匹配类型被编译器视为不匹配类型并导致 Xcode 12.0 中的编译错误。
您能否为此提供任何好的解决方案?将不胜感激。
谢谢。
更新: 在将参数类型更改为在块中包含“NSCopying”协议后(使参数类型的协议设置与“CC3ShaderProgram”相同),Xcode12 编译器已停止抱怨。 (以前只包含 CC3Cacheable 协议。)
-(void) enumerateObjectsUsingBlock: (void (^) (id<CC3Cacheable, NSCopying> obj, BOOL* stop)) block
目前,代码二进制构建没有此编译错误。但是,我仍然不明白为什么 Xcode 12.0 会抱怨这个,除非 Xcode12 的 CLANG 在类型检查方面比以前的版本严格得多。
【问题讨论】:
标签: objective-c objective-c-blocks cocos3d xcode12