ios - 如何防止线程打印在控制台中混合输出?

标签 ios swift multithreading logging swift4

假设我们有多个线程发出打印。 通常在下载内容时如下:

let url = self.url
print("loadPreview(\(source) for \(url)): ↝start loading \(self.url")
let task = session.downloadTask(with: url) { 
    (localUrl, response, error) in
    print("loadPreview(\(source) for \(url)): == \(self.url")
}

有什么方法可以使打印原子化并防止输出如下?

loadPreview(WSJ for www.wsj.co⟷TloadPreview(9loadPreview(appleins   for appleinsid⟷n-messages):     ↝start loading http://app⟷n-messages

最佳答案

快速破解就是使用 NSLock在你的打印品周围。例如,您可以将原子打印函数定义为:

private let printLock = NSLock()

func aprint(_ message: String){
    printLock.lock()
    defer { printLock.unlock() }
    print(message)
}

并像标准的 print 函数一样使用它:

aprint(“This will print atomically!”)

您也可以使用序列号 DispatchQueue 获得类似的结果也可以序列化您的打印调用。例如:

private let printQueue = DispatchQueue(label: "aprint", qos: .utility)

func aprint(_ message: String){
    printQueue.async {
        print(message)
    }
}

这个解决方案提供了更好的性能,这主要归功于 async 调用。这可确保调用线程不会阻塞,直到获得锁(并且相应的print 已完全执行)。但是,需要明确的是,这个解决方案也是完全原子的。

(郑重声明,如果调用代码在主队列上运行,则简单地使用 DispatchQueue.main 可能会表现得很奇怪。)

我建议选择第二种解决方案;)

关于ios - 如何防止线程打印在控制台中混合输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47105132/

相关文章:

ios - 有没有办法使用 XCTest 对 Touch Id 进行单元测试?

objective-c - 更改模态 UIActivityViewController 的外观

swift - playAtTime 如何运作? ( swift 进入)

swift - 可打印字符串插值不起作用

c# - 如何使用线程完成,然后重用线程?

c# - 获取所有打开的窗口

ios - 'initialize()' 的使用不明确

iphone - 有没有办法识别在父 uitableview 中选择的单元格

ios - 如何使用 CoreData 和 CloudKit 处理离线模式?

java - 在 Scala 中执行多线程的推荐方法是什么