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

时间:2019-06-06 21:55:13

标签: swift c-preprocessor swiftui

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

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

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

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

5 个答案:

答案 0 :(得分:9)

注意:要更加明确,您不要需要将您的预览提供程序包装在#if DEBUG条件中。它们将从您的生产版本中删除。

我来晚了一点,但我只需要记下这一点,因为混乱遍布网络,事实证明这很可笑。该发行说明位于“ 已解决的问题”下,已解决的故障单的标题为“ 在归档时未从构建产品中正确删除PreviewProviders(51539802)”。

是的,现在一切都有意义了。

The still The proof

Annnd Just in case you think they may have changed it later..... more proof

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

答案 1 :(得分:9)

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

#if DEBUG

class MyServiceMock: ServiceMockType {
    ...
}

#endif

struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(service: MyServiceMock())
    }
}

这适用于测试和预览,但在您尝试发布时会失败。因此,尽管它们不是必需的,但如果您使用任何仅为 Debug 声明的代码,则需要它们。

答案 2 :(得分:4)

它似乎已从11 GM种子中删除。 GM种子发行说明说(在“已解决的问题”下):

“已从SwiftUI模板中删除了有关PreviewProvider类型的#if /#endif编译器条件。存档时未正确从构建产品中删除PreviewProvider。(51539802)”

不确定这是否意味着预览提供程序当前未被删除,或者他们已解决了问题并立即将其删除。我想如果模板代码删除了#,即表示Apple认为不再需要该代码。

答案 3 :(得分:0)

您不需要删除它。 DEBUG是一个自定义标志,已自动添加到Your Target -> Build Settings -> Active compilation Conditions中。此标志仅在Debug配置中存在,对于发布版本,您将使用不具有此标志的Release配置。

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

Read more here在“ DEBUG预处理程序宏”部分

答案 4 :(得分:0)

Xcode 11.2和更高版本不需要#if DEBUG,因此,您可以执行以下操作并删除PreviewProvider周围的#if DEBUG

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                Text("First Row")
                Text("First Row")
                Text("First Row")
                Text("First Row")
            }.navigationBarTitle(Text("Dynamic List"))
        }
    }

}



struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}