28

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

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

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

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

4

5 回答 5

22

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

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

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

静止 的证明

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

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

于 2020-02-29T08:47:28.843 回答
14

对于您的特定情况,您可以删除#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())
    }
}

这对于测试和预览效果很好,但在您尝试发布时会失败。

尽管它们不是必需的,但如果您使用任何仅为Debug. 如果您在预览中使用了仅可用于调试的代码,我的建议是保留它们。

#if DEBUG

class MyServiceMock: ServiceMockType {
    ...
}

#endif

...

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView(service: MyServiceMock())
    }
}
#endif
于 2021-03-02T10:31:08.223 回答
4

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

“已从 SwiftUI 模板中删除了围绕 PreviewProvider 类型的 #if/#endif 编译器条件。存档时,预览提供程序未从构建的产品中正确删除。(51539802)”

不确定这是否意味着当前未删除预览提供程序,或者他们修复了问题并现在将其删除。我想如果模板代码删除了 #if 这意味着 Apple 认为它不再需要。

于 2019-09-12T22:29:06.330 回答
2

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()
    }
}
于 2019-11-12T15:08:47.373 回答
-1

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

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

在“调试预处理器宏”部分中阅读更多信息

于 2019-06-06T23:07:57.780 回答