在SwiftUI中预览是否真的需要#if DEBUG语句才能在发布版本中将其删除?

J. *_*Doe 7 c-preprocessor swift swiftui

预处理宏在SwiftUI官方教程/视频中很常见,例如:

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

需要这些吗?编译器肯定可以看到在struct内部未使用,并且struct由于access修饰符是隐式的,所以省略了整体internal吗?我认为符合条件的所有内容PreviewProvider都可以删除,但是并不是每个符合条件的对象都如此,但是如果不使用它,Apple为什么决定包括预处理器宏?

我试图在发布模式下运行它,并在派生数据文件夹中找到已编译的类,但是我对此一无所知(.o文件)。任何人都可以确认我们是否真的需要包括宏以省略未使用的代码(ContentView_Previews类型在预期用于预览的代码中未在任何地方使用,无论如何在该版本中均未使用),该版本是否已发布?

Dav*_*rel 16

:要格外清楚,你不要需要来包装你预览提供商#if DEBUG条件语句。它们将从您的生产版本中删除。

我有点晚了,但我只需要记下这一点,因为网络上到处都是混乱,结果证明它很可笑。发行说明位于“已解决的问题”下,解决票证的标题是“存档时未从构建的产品中正确删除 PreviewProviders。( 51539802) ”。

是的,现在一切都说得通了。

仍然 证明

Annnd 以防万一你认为他们以后可能会改变它..... 更多证据

(我很彻底......也许太多了)

  • 我使用的是 Xcode 14.2,并且看到 Xcode 11 的修复可能会出现回归:“任何 iOS 设备”构建成功,但 Archive 构建_do_ 包含 PreviewProviders。在我的例子中,那些通常被排除的 PreviewProvider 引用了一些用“#if DEBUG/#endif”包装的调试示例数据变量,因此存档构建失败。所有其他构建类型都会成功。向 Apple 提交的文件编号为 FB11920041。 (8认同)
  • 如果我使用 PreviewContent 文件夹中的代码,我必须添加 DEBUG 条件。 (2认同)

Mih*_*scu 11

对于您的特定情况,您可以删除#if DEBUG宏,但是当您想使用#if DEBUG宏内部的一些模拟时就会出现问题。Release 的构建将失败,因为看起来 Xcode 仍会尝试构建PreviewProvider,很可能在构建后它会从 Release 工件中剥离或取消链接代码。

#if DEBUG

class MyServiceMock: ServiceMockType {
    ...
}

#endif

// Will fail when you try to release.

struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(service: MyServiceMock())
    }
}
Run Code Online (Sandbox Code Playgroud)

这对于测试和预览效果很好,但在您尝试发布时会失败。因此,尽管它们不是必需的,但如果您使用任何仅为Debug.


Den*_*Fav 0

您不需要删除它。DEBUG 是自动添加到Your Target -> Build Settings -> Active compilation Conditions. 此标志仅适用于调试配置,对于发布版本,您将使用没有此标志的发布配置。

如果该标志不存在 - 代码将被省略

在“DEBUG 预处理器宏”部分中了解更多信息

  • 我认为你误解了这个问题。OP 询问在这种情况下是否确实需要 `if DEBUG` `endif` 预处理器。关键是预览代码显然是调试代码,所以我们是否需要显式地将其标记为调试代码,或者编译器是否足够聪明,可以找出并在没有宏的情况下从输出构建中省略它? (2认同)