objective-c - Xcode12 针对 Cocos3D 编译错误 : Incompatible block pointer types

标签 objective-c objective-c-blocks cocos3d xcode12

“Xcode 12.0 (12A7209)”在以下代码中显示针对 Cocos3D 库(用 Objective-C 编写)的编译错误:
(过去版本的 Xcode((即版本 11、10),包括版本 11.7(11801a))没有此问题,但 Xcode 12.0 有。)

错误消息:
不兼容的 block 指针类型将“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 编译器提示 block “enumerateObjectsUsingBlock:”的输入参数的对象类型不匹配。

但是“CC3ShaderProgram”继承自“具有CC3Cacheable协议(protocol)的NSObject”,如下所示:

@interface CC3ShaderProgram : CC3Identifiable 
@interface CC3Identifiable : NSObject <CC3Cacheable, NSCopying>

因此,“CC3ShaderProgram”是与“id”匹配的类型,因此编译器不应该提示,但 Xcode12.0 会提示。

不仅在“willBeginDrawingScene”处,而且在库中使用“enumerateObjectsUsingBlock:”的其他地方也存在同样的问题。

过去几年我一直在几个不同版本的 Xcode 中使用 Cocos3D 库,没有出现这个问题。

“Xcode 12.0”的 CLANG 或 SDK 中是否进行了任何更改,以在 block 参数类型检查方面变得更加严格(例如“不允许使用通用对象指针“id””)?否则,我不明白为什么这两个匹配类型会被编译器视为不匹配类型,并导致 Xcode 12.0 中编译错误。

您能提供什么好的解决方案吗?我们将不胜感激。

谢谢。

更新: 将参数类型更改为在 block 中包含“NSCopying”协议(protocol)(以使参数类型的协议(protocol)设置与“CC3ShaderProgram”相同)后,Xcode12 编译器已停止提示。 (以前,仅包含 CC3Cacheable 协议(protocol)。)

-(void) enumerateObjectsUsingBlock: (void (^) (id<CC3Cacheable, NSCopying> obj, BOOL* stop)) block

目前,生成的代码二进制文件没有出现此编译错误。但是,我仍然不明白为什么 Xcode 12.0 会提示这一点,除非 Xcode12 的 CLANG 在类型检查方面比以前的版本变得更加严格。

最佳答案

在 Cocos3D 中有两种方法可以解决这个问题。

可以通过将 __kindof 添加到 [CC3Cache enumerateObjectsUsingBlock:] 的定义中来修复 CC3Cache.h 中的代码,如下所示:

-(void) enumerateObjectsUsingBlock: (void (^) (__kindof id<CC3Cacheable> obj, BOOL* stop)) block;

这是应该修复的地方。

或者,可以在构建时消除错误,而无需更改代码,方法是:

-Xclang -fcompatibility-qualified-id-block-type-checking

OTHER_CFLAGS build设置中。

这些解决方案的原始来源可以找到herehere .

关于objective-c - Xcode12 针对 Cocos3D 编译错误 : Incompatible block pointer types,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63940355/

相关文章:

objective-c - 使用 Jastor 将 JSON/NSDictionary 转换为 Typed Swift 类

objective-c - NSMutableArray + NSEnumeration并发内存错误

objective-c - block 和堆栈

iphone - 如何在 cocos3d 中导入 3ds max 模型 iPhone 示例

objective-c - for 循环的差异。 swift vs. Objective-C

ios - AFNetworking GET 函数未更改的变量

iphone - 拔下耳机时是否有事件?

ios - block 内的强弱。我该如何处理这个问题?

ios - Z 轴支持查看 UIView

ios - Cocos3d 中遇到障碍物时停止