print参数 swift

2016-04-22 15:03:33 wj610671226 阅读数 4961

Swift中Debug和Release两种状态下print()函数调试切换

       在编写项目的过程中,我们常常会打印信息到控制台,通过打印的信息来判断代码的流程或者正确性。但是这些信息仅仅在Debug的状态下需要,一旦版本发布之后,我们就不需要这些打印操作了。如果是在发布版本之前,程序员手动一个个的去注释或者删除打印操作,这必然是一件浪费时间而又麻烦的事情。如果不处理,上线的版本运行在手机中,这些打印操作势必会影响一些性能的。下面就记录一下在项目中如何处理。

一、在OC代码中,我们常常会通过一个宏定义来控制打印操作

#ifdef DEBUG
#define MyLog(...) NSLog(__VA_ARGS__)
#else
#define MyLog(...)
#endif

二、在Swift中我一般使用下面两种方法来控制

1、自己写一个工具类 DebugLogTool, 通过控制isDebug 的值来控制打印情况,有点点不智能哈

2、通过配置工程文件,加上工具类 DebugLogTool

2017-06-14 16:44:06 mydo 阅读数 906

尽管print声明不会在设备的console里打印,但它们甚至在Release版本和设备上也会执行,这些执行可能会带来一些耗费。

特别的,它的参数仍然被模拟求值。如果你的print调用只有一个参数,这里有一个变通方法。你可以通过定义自己的全局级别的print方法来重写Swift的print方法,并且使用@autoclosure修饰器推迟其参数求值,就像assert做的那样:

func print(_ item: @autoclosure () -> Any,
        separator: String = " ", terminator: String = "\n") {
            #if DEBUG
            Swift.print(item(), separator:separator, terminator: terminator)
            #endif
}

当你调用print(myExpensiveFunction())时,这个定制print方法被调用。这意味着在闭包中包裹的myExpensiveFunction()方法不会被立即求值。

如果你只在Swift的Debug配置标志中定义了-DDEBUG,那么在Release配置下构建的app中,myExpensiveFunction()将永远不会被求值,因为item()不会被调用。

2015-12-30 23:08:54 magic_castle 阅读数 5442

Log 输出是程序开发中很重要的组成部分,虽然它并不是直接的业务代码,但是却可以忠实地反映我们的程序是如何工作的,以及记录程序运行的过程中发生了什么。

在 Swift 中,最简单的输出方法就是使用 print,在我们关心的地方输出字符串和值。但是这并不够,试想一下当程序变得非常复杂的时候,我们可能会输出很多内容,而想在其中寻找到我们希望的输出其实并不容易。我们往往需要更好更精确的输出,这包括输出这个 log 的文件,调用的行号以及所处的方法名字等等。

我们当然可以在 print 的时候将当前的文件名字和那些必要的信息作为参数同我们的消息一起进行打印:

// Test.swift
func method() {  
    //...
    print("文件名:Test.swift, 方法名:method,这是一条输出")
    //...
}

但是这显然非常麻烦,每次输入文件名和方法名不说,随着代码的改变,这些 Log 的位置也可能发生改变,这时我们可能还需要不断地去维护这些输出,代价实在太大。

在 Swift 中,编译器为我们准备了几个很有用的编译符号,用来处理类似这样的需求,它们分别是:

符号 类型 描述
FILE String 包含这个符号的文件的路径
LINE Int 符号出现处的行号
COLUMN Int 符号出现处的列
FUNCTION String 包含这个符号的方法名字

因此,我们可以通过使用这些符号来写一个好一些的 Log 输出方法:

func printLog<T>(message: T,  
                    file: String = __FILE__,
                  method: String = __FUNCTION__,
                    line: Int = __LINE__)
{
    print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
}

这样,在进行 log 的时候我们只需要使用这个方法就能完成文件名,行号以及方法名的输出了。最棒的是,我们不再需要对这样的输出进行维护,无论在哪里它都能正确地输出各个参数:

// Test.swift
func method() {  
    //...
    printLog("这是一条输出")
    //...
}

// 输出:
// Test.swift[62], method(): 这是一条输出

另外,对于 log 输出更多地其实是用在程序开发和调试的过程中的,过多的输出有可能对运行的性能造成影响。在 Release 版本中关闭掉向控制台的输出也是软件开发中一种常见的做法。如果我们在开发中就注意使用了统一的 log 输出的话,这就变得非常简单了。使用条件编译的方法,我们可以添加条件,并设置合适的编译配置,使 printLog 的内容在 Release 时被去掉,从而成为一个空方法:

func printLog<T>(message: T,  
                    file: String = __FILE__,
                  method: String = __FUNCTION__,
                    line: Int = __LINE__)
{
    #if DEBUG
    print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
    #endif
}

新版本的 LLVM 编译器在遇到这个空方法时,甚至会直接将这个方法整个去掉,完全不去调用它,从而实现零成本。

2020-01-16 21:16:11 bobbob32 阅读数 118

直接贴代码了,可以支持多参数,在别人基础上进行修改

public func Fprint(_ items: Any...,
                    separator: String = " ",
                   terminator: String = "\n",
                   _ file:String = #file,
                   _ function:String = #function,
                   _ line:Int = #line){
  
    
    var longStr:String = ""
    for value in items{
        var stringRepresentation:String = ""
        if let value = value as? CustomStringConvertible{
            stringRepresentation = value.description
        }else if let value = value as? CustomDebugStringConvertible{
            stringRepresentation = value.debugDescription
        }else if let value = value as? LosslessStringConvertible{
            stringRepresentation = value.description
        } else{
            //            fatalError("glog only work for values that conform to CustomStringConvertible or CustomDebugStringConvertible")
            //            print(objct)
        }
        longStr = longStr + "," + stringRepresentation
    }
    
    let gFormatter = DateFormatter()
    gFormatter.dateFormat = "HH:mm:ss:SSS"
    let timeStamp = gFormatter.string(from: Date())
    let queue = Thread.isMainThread ? "UI":"BG"
    let fileUrl = NSURL(string: file)?.lastPathComponent ?? "Unknown file"
    
    if longStr.count > items.count{
        print("FM \(timeStamp) {\(queue)} \(fileUrl) > \(function)[\(line)]: \(longStr)")
    }else{
        print("FM \(timeStamp) {\(queue)} \(fileUrl) > \(function)[\(line)]: \(items)")
    }
}

参考文章

2016-10-10 01:16:24 u012903898 阅读数 4352

Swift 变量名
Swift 可以通过:声明特定类型的变量
数据类型首字母大写

let lxyInt : Int = 3
let lxyFloat : Float = 3.14
let lxyDouble : Double = 3.1415926
let lxyCGFloat : CGFloat = 9.0
let lxyBool : Bool = true
let lxyString : String = "Hello,Swift"

Swift变量名称可以用unicode任意字符,可以用中文和表情符号

var 名字 = "lxy"
print("我的名字是" + 名字)

print的基本用法

//print函数使用
print("hellow")
let x = 1, y = 2, z = 3
print(x,y,z)

let b = true
print(b)//true

print(x,y,z, separator: "--")
//1--2--3
//separator设置分割符,默认是" "

print(x,y,z, separator: "--", terminator:":)")
//1--2--3:)
//terminator结束符,默认为回车


print(y,"*",z,"=",y*z)
//2 * 3 = 6
//字符串插值
print("\(y) * \(z) = \(y*z)")
//2 * 3 = 6

Swift4.0 外部参数

阅读数 293