在发布版本的iOS Swift中删除println()。

13 浏览
0 Comments

在发布版本的iOS Swift中删除println()。

如果我不是在调试构建中,我想要在我的Swift代码中全局忽略所有的println()调用。我找不到任何详细的步骤说明,希望得到指导。有没有一种全局的方法来做到这一点,还是我需要用#IF DEBUG/#ENDIF语句包围每个println()

0
0 Comments

问题:在发布版本的iOS Swift中,如何移除println()函数?

原因:为了在发布版本的iOS Swift中移除println()函数,可以通过以下几种方法来实现:

1. 创建一个全局函数print(),并在其中调用Swift的println()函数。当需要停止日志记录时,只需注释掉print()函数的内容即可。

2. 使用条件编译,通过#if DEBUG来控制是否执行println()函数。

3. 在Swift 2.0中,println()被改为print(),并且现在有一个可变参数作为第一个参数。可以创建一个简化版本的print()函数,只打印第一个参数。

4. 在Swift 3中,需要去除print()函数的第一个参数的外部标签。

解决方法:根据以上原因,可以采用以下解决方法来移除println()函数:

1. 创建一个全局函数print(),并在其中调用Swift的println()函数。当需要停止日志记录时,只需注释掉print()函数的内容即可。

func print(object: Any) {

Swift.println(object)

}

2. 使用条件编译,通过#if DEBUG来控制是否执行println()函数。

func print(object: Any) {

#if DEBUG

Swift.println(object)

#endif

}

3. 在Swift 2.0中,println()被改为print(),并且现在有一个可变参数作为第一个参数。可以创建一个简化版本的print()函数,只打印第一个参数。

func print(items: Any..., separator: String = " ", terminator: String = "\n") {

Swift.print(items[0], separator:separator, terminator: terminator)

}

4. 在Swift 3中,需要去除print()函数的第一个参数的外部标签。

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {

Swift.print(items[0], separator:separator, terminator: terminator)

}

通过以上方法,可以在发布版本的iOS Swift中移除println()函数,从而提高代码的可读性和性能。

0
0 Comments

在Swift 4.x中进行了更新:

随着Swift 2.0/3.0和Xcode 7/8的正式发布,禁用发布版本中的打印功能的方法发生了一些变化。

以下是Birkholz提到的一些重要事项:

1. println()函数已被print()替代。

2. 要使用#if DEBUG宏,您必须将"Swift Compiler - Custom Flags - Other Flags"定义为包含值-D DEBUG

3. 我建议在全局范围内重写Swift.print()函数,这样您可以在代码中正常使用print()函数,但它将删除非调试版本的输出。以下是在Swift 2.0/3.0中可以添加到全局范围的函数签名:

func print(items: Any..., separator: String = " ", terminator: String = "\n") {

#if DEBUG

var idx = items.startIndex

let endIdx = items.endIndex

repeat {

Swift.print(items[idx], separator: separator, terminator: idx == (endIdx - 1) ? terminator : separator)

idx += 1

}

while idx < endIdx

#endif

}

注意:我们在这里将默认分隔符设置为空格,默认终止符设置为换行符。如果需要,您可以在项目中进行不同的配置。

希望对您有所帮助。

更新:

通常最好将此函数放在全局范围内,以便它位于Swift的print函数之前。我发现最好的组织方式是在项目中添加一个实用文件(例如DebugOptions.swift),在其中将此函数放在全局范围内。

从Swift 3开始,++运算符将被弃用。我已经更新了上面的代码片段以反映这个变化。

对不起,但是在哪里放置这个函数?

您可能希望将此函数放在全局范围内,以便在整个项目中都可以访问它。在我的项目中,我会添加一个实用的Swift文件(例如DebugOptions.swift),并将此函数放在全局范围内(即不在一个封闭类中)。

您能确认在当前版本的Swift-Xcode中,不需要设置-D Debug标志,打印语句将不再输出到设备控制台吗?至少这是我今天测试的结果。

截至Xcode 7.3,如果您想要在调试模式下打印调试输出,您仍然需要设置调试标志,根据我的测试结果。

从Swift 3开始,通过在参数列表的开始处添加一个下划线可以更简洁一些:"print (_ items..."

我对Swift(3)还不熟悉,我将上面的print放入了自己的Swift文件中,但它没有起作用。

然后我查阅了print的参考(在didFinishLaunching中使用...),它指向了Swift中的原始print函数。根据's的评论,我调整了函数的样子,像这样它就起作用了:public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {

将其添加到项目中的任何位置,但在类之外,并注意覆盖print函数的参数,因为它与上面稍有不同。尝试使用func print(_ items: Any..., separator: String = " ", terminator: String = "\n")在items参数中添加下划线。

不起作用,编译错误:Invalid redeclaration of 'print(_:separator:terminator:)'

0
0 Comments

在发布版本的iOS Swift中,我们希望移除打印输出语句println(),以减少运行时的开销。现有的解决方案都无法解决评估print参数的开销问题。为了解决这个问题,我们可以通过条件编译来包裹实际的打印调用,只在调试版本中执行打印语句,而在发布版本中不执行。具体做法是在代码中添加#if DEBUG#endif来限制打印语句的执行。此外,我们还可以使用autoclosure来延迟参数的评估,进一步减少开销。下面是一种可能的解决方案(Swift 3):

func print(_ item: () -> Any, separator: String = " ", terminator: String = "\n") {

#if DEBUG

Swift.print(item(), separator: separator, terminator: terminator)

#endif

}

这种解决方案只适用于打印单个参数的情况,因为item()在发布版本中不会被调用,所以不会产生额外的开销。这样,即使在使用print(myExpensiveFunction())这样的打印语句时,也不会产生昂贵的开销。

另外,关于的用法,它是用来表示代码的起始和结束位置的标记。

在你的书中提到,“print”的一个重要特性是,在独立于Xcode运行应用程序时,它将被有效地禁止。这意味着我们现在可以在提交的应用程序中保留打印语句吗?或者我有什么误解吗?

是的,我倾向于在发布版本的代码中保留print语句,但这与我在这里的回答有所不同。在独立于Xcode的发布版本中,print语句的输出不会发送到控制台,但它仍然会被评估。因此,了解如何禁止评估非常有用,以防止它产生昂贵的开销或产生不需要的副作用。

好的,我误解了。我将注释掉这些语句。谢谢!

使用这种方法,打印的字符串会被移除吗?例如,如果我在我的应用程序中使用了print("user logged in"),那么如果有人试图对我的应用程序进行反向工程,他能找到这个字符串吗,或者根本不会有这个字符串?

我建议还添加(*, unavailable, message: "Use single argument print(item: Any) instead") func print(_ items: Any..., separator: String = " ", terminator: String = "\n") { },以避免误用多参数的打印语句。

好主意!

0