【问题标题】:'SWIFT_NORETURN' macro redefined'SWIFT_NORETURN' 宏重新定义
【发布时间】:2021-07-26 19:36:28
【问题描述】:

在 Xcode 12.5 上,当我尝试编译我的测试目标时得到这个:

/Users/user/Development/project-ios/My ProjectTests/My ProjectTests-Bridging-Header.h:7:9: note: in file included from /Users/user/Development/project-ios/My ProjectTests/My ProjectTests-Bridging-Header.h:7:
#import "SpecHelper.h"
        ^
/Users/user/Development/project-ios/My ProjectTests/SpecHelper.h:36:9: note: in file included from /Users/user/Development/project-ios/My ProjectTests/SpecHelper.h:36:
#import "My_Project-Swift.h"
        ^
/Users/user/Library/Developer/Xcode/DerivedData/My._Project-eybfcywypdtewfbihzpxuwyltrxw/Build/Intermediates.noindex/My Project.build/Debug-iphonesimulator/My Project.build/DerivedSources/My_Project-Swift.h:98:10: error: 'SWIFT_NORETURN' macro redefined
# define SWIFT_NORETURN __attribute__((noreturn))
         ^
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.5.sdk/usr/lib/swift/shims/Visibility.h:86:9: note: previous definition is here
#define SWIFT_NORETURN __attribute__((__noreturn__))
        ^
<unknown>:0: error: failed to import bridging header '/Users/user/Development/project-ios/My ProjectTests/My ProjectTests-Bridging-Header.h'
Command MergeSwiftModule failed with a nonzero exit code

项目-Swift.h

#if __has_attribute(noreturn)
# define SWIFT_NORETURN __attribute__((noreturn))
#else
# define SWIFT_NORETURN
#endif

和 Visibility.h

#if __has_attribute(noreturn)
#define SWIFT_NORETURN __attribute__((__noreturn__))
#else
#define SWIFT_NORETURN
#endif

注意:这适用于 Xcode 12.4。

知道如何解决这个问题吗?

更新(5 月 27 日):如果我删除派生数据,运行测试套件会失败并出现上述错误。尝试第二次运行它似乎有效。我不知道为什么会这样。

更新 2:(6 月 3 日):问题似乎是我在 .h 文件中定义了一个类,该类符合 swift 文件中定义的协议,不同的目标。 This 解释了为什么我不能使用前向声明,所以我不必导入“MyProject-Swift.h”文件。

【问题讨论】:

  • 您是否尝试删除重新定义?
  • 见下文@EmilioPelaez,我不是自己添加定义,而是在“My-Project.swift”文件中生成一个,另一个似乎是模拟器中的“垫片” “../shims/Visibility.h”文件。我无法改变我所相信的。

标签: ios swift xcode ios14 xcode12.5


【解决方案1】:

我不清楚为什么要在不同的地方声明宏,但必须有循环导入或最终重新定义的东西。

选项 1 是重构代码,以便您只在一个位置声明该宏,然后从必要的位置导入它。

选项 2 是包装每个声明,使其不会被重新定义:

#ifndef SWIFT_NORETURN

#if __has_attribute(noreturn)
#define SWIFT_NORETURN __attribute__((__noreturn__))
#else
#define SWIFT_NORETURN
#endif

#endif

或者:

#if __has_attribute(noreturn) && !defined(SWIFT_NORETURN)
#define SWIFT_NORETURN __attribute__((__noreturn__))
#else
#define SWIFT_NORETURN
#endif

【讨论】:

  • 抱歉耽搁了。是的,我认为它恰好涉及循环导入,但我没有明确声明它,这意味着我将无法检查它是否存在。项目目标在SpecHelper.h 文件中导入:“#import "My_Project-Swift.h" 最终与Visibility.h 中定义的目标冲突。我将无法更改其中任何一个假设。
【解决方案2】:

尝试检查,您的头文件不包含行#import "Project-Swift.h"。理想情况下,只有*.m 文件应该包含这个生成的标头。

https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c

【讨论】:

  • 感谢@ZGI6YXNt 的提示。我认为我的问题是我在 .h 文件中有一个类,它符合 swift 文件中定义的协议,不同的目标。我试图通过转发声明协议来解决这个问题,但我认为这是不可能的,因为编译器需要验证一致性,因此它需要整个声明。 stackoverflow.com/a/11091897/429763
  • 解决这个问题有几种不同的方法,例如,你可以用swift完全重写这个类,或者只重写负责符合协议的部分。如果由于某种原因不适合,还有其他选择。
猜你喜欢
  • 1970-01-01
  • 2019-08-05
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多