Xcode从8升级至9.3.1遇'id<NSCopying>'字典读取错误求助
解决Xcode 9.3.1中
id<NSCopying>类型的字典访问错误 这个问题我之前帮不少升级Xcode的开发者排查过,本质是Xcode 9.3.1搭载的Clang编译器对静态类型检查变得更严格了:你的options变量类型是id<NSCopying>,它仅表示对象实现了NSCopying协议,但编译器无法确定它就是NSDictionary(毕竟NSString、NSArray等很多类都实现了该协议),因此不认可字典下标[]的访问语法——只有NSDictionary/NSMutableDictionary才有这个下标方法,这就是报错的核心原因。
下面给你两种直接可行的解决方向:
方案1:强制类型转换明确字典类型
在访问options时,直接将其转换为NSDictionary*,让编译器明确知道这是一个字典实例。你可以选择逐行转换,或者先声明局部变量统一转换(后者更整洁):
逐行转换示例
// Normalize the blending mode to use for the key. id src = (((NSDictionary*)options)[CCBlendFuncSrcColor] ?: @(GL_ONE)); id dst = (((NSDictionary*)options)[CCBlendFuncDstColor] ?: @(GL_ZERO)); id equation = (((NSDictionary*)options)[CCBlendEquationColor] ?: @(GL_FUNC_ADD)); NSDictionary *normalized = @{ CCBlendFuncSrcColor: src, CCBlendFuncDstColor: dst, CCBlendEquationColor: equation, // Assume they meant non-separate blending if they didn't fill in the keys. CCBlendFuncSrcAlpha: (((NSDictionary*)options)[CCBlendFuncSrcAlpha] ?: src), CCBlendFuncDstAlpha: (((NSDictionary*)options)[CCBlendFuncDstAlpha] ?: dst), CCBlendEquationAlpha: (((NSDictionary*)options)[CCBlendEquationAlpha] ?: equation), };
局部变量统一转换示例
NSDictionary *optionsDict = (NSDictionary*)options; id src = (optionsDict[CCBlendFuncSrcColor] ?: @(GL_ONE)); id dst = (optionsDict[CCBlendFuncDstColor] ?: @(GL_ZERO)); id equation = (optionsDict[CCBlendEquationColor] ?: @(GL_FUNC_ADD)); NSDictionary *normalized = @{ CCBlendFuncSrcColor: src, CCBlendFuncDstColor: dst, CCBlendEquationColor: equation, CCBlendFuncSrcAlpha: (optionsDict[CCBlendFuncSrcAlpha] ?: src), CCBlendFuncDstAlpha: (optionsDict[CCBlendFuncDstAlpha] ?: dst), CCBlendEquationAlpha: (optionsDict[CCBlendEquationAlpha] ?: equation), };
方案2:用objectForKey:替代下标访问
字典的objectForKey:是经典实例方法,id类型可以直接调用该方法(编译器不会报错),不过要注意:运行时如果options不是NSDictionary实例会崩溃,所以你要确保传入的options确实是字典:
// Normalize the blending mode to use for the key. id src = ([options objectForKey:CCBlendFuncSrcColor] ?: @(GL_ONE)); id dst = ([options objectForKey:CCBlendFuncDstColor] ?: @(GL_ZERO)); id equation = ([options objectForKey:CCBlendEquationColor] ?: @(GL_FUNC_ADD)); NSDictionary *normalized = @{ CCBlendFuncSrcColor: src, CCBlendFuncDstColor: dst, CCBlendEquationColor: equation, // Assume they meant non-separate blending if they didn't fill in the keys. CCBlendFuncSrcAlpha: ([options objectForKey:CCBlendFuncSrcAlpha] ?: src), CCBlendFuncDstAlpha: ([options objectForKey:CCBlendFuncDstAlpha] ?: dst), CCBlendEquationAlpha: ([options objectForKey:CCBlendEquationAlpha] ?: equation), };
额外优化建议
如果options参数的定义权限在你手里,建议直接把它的类型从id<NSCopying>改成NSDictionary*(或者NSDictionary<NSCopying, id>*,如果键需要支持拷贝),从根源上避免这类类型检查错误,代码可读性也会更高。
内容的提问来源于stack exchange,提问作者BTVC
相关产品推荐
相关产品推荐

