@attached宏在SwiftUI预览体中是否生效?相关报错咨询
问题:@attached宏在SwiftUI预览体中是否可以正常工作?
我编写了一个可生成单个模拟实例的MockBuilder宏,给DeveloperCardViewParameters结构体添加了mock属性,但在SwiftUI预览中报错提示Type 'DeveloperCardViewParameters' has no member 'mock'。
结构体代码:
@MockBuilder() struct DeveloperCardViewParameters { let icon: Image let title: String let description: String #if DEBUG static var mock: DeveloperCardViewParameters { .init( icon: MockBuilderSupportedType.generate(elementType: .image, generatorType: .random) as! Image, title: MockBuilderSupportedType.generate(elementType: .string(), generatorType: .random) as! String, description: MockBuilderSupportedType.generate(elementType: .string(), generatorType: .random) as! String ) } #endif }
预览代码:
#if DEBUG #Preview(body: { DeveloperCardView(parameters: DeveloperCardViewParameters.mock) // 报错:"Type 'DeveloperCardViewParameters' has no member 'mock'" }) #endif
解答
@attached宏完全可以在SwiftUI预览环境中正常工作,你遇到的报错是代码写法或宏实现逻辑的问题,并非预览本身不支持宏。
问题原因分析:
- 手动代码与宏逻辑冲突:你在结构体中手动编写了
static var mock,同时又使用了@MockBuilder宏。如果该宏的设计目标是自动生成mock属性,两者可能产生冲突,导致宏生成的属性被覆盖,或者手动代码被宏处理后移除。 - 宏定义不规范:如果你的
MockBuilder宏没有正确使用@attached(member)语法来指定附加静态属性,宏无法正确将mock属性注入到结构体中。 - Xcode缓存问题:宏的展开缓存可能出现异常,导致预览环境无法识别生成的mock属性。
修复建议:
- 移除手动编写的mock代码:如果
MockBuilder宏的作用是自动生成mock实例,直接删掉结构体中#if DEBUG块内的手动代码,交由宏完成生成。 - 检查宏定义语法:确保宏的定义正确使用
@attached(member)来声明要附加的静态成员,示例如下:@attached(member, names: named(mock)) public macro MockBuilder() = #externalMacro(module: "YourMacroModule", type: "MockBuilderMacro") - 验证宏实现逻辑:在宏的实现代码中,确保只在
DEBUG环境下生成mock属性,并且正确处理Image、String等类型的实例生成。 - 清理缓存并重启Xcode:使用
Cmd+Shift+K清理项目缓存,重启Xcode后再尝试预览,解决宏展开缓存异常的问题。
内容的提问来源于stack exchange,提问作者Rezo Joglidze
相关产品推荐
相关产品推荐

