Swift 使用 NSTimer 时无法输出

Swift cannot output when using NSTimer

我尝试使用 NSTimer.

每秒输出到 STDOUT

我写了下面的代码,保存为sample.swift。

#!/usr/bin/swift

import AppKit

class Foo : NSObject {
  override init() {
    super.init()
    NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "bar", userInfo: nil, repeats: true)
  }

  func bar() {
    print("buz")
  }
}

let h = Foo()

// Output successful
// while true {
//   print("Foo!")
// }

NSRunLoop.mainRunLoop().run()

然后,我执行了下面的命令,可以看到buz.

okada@iyokan$ ./sample.swift
buz
buz
buz
buz

所以,我执行了以下命令,但我看不到任何 buz

okada@iyokan$ ./sample.swift > sample.log # wait 5 seconds
okada@iyokan$ cat sample.log
okada@iyokan$ 

顺便说一句,我试过while循环版本(激活注释掉上面的代码)然后我可以通过两个程序得到buz

为什么我没有得到buz? 请教我。

这是 stdio 库的 "normal" 行为。文件描述符 可以是"buffered",表示所有printf()和 其他输出操作首先进入内部缓冲区。当那个 缓冲区达到一定大小(如8KB),其内容被写入实际 文件。

三种模式:"unbuffered"(所有输出都写入文件 立即),"line buffered"(收集输出直到换行符 打印字符), 和 "fully buffered".

根据Is stdout line buffered, unbuffered or indeterminate by default?

Unix convention is that stdin and stdout are line-buffered when associated with a terminal, and fully-buffered (aka block-buffered) otherwise.

这解释了为什么您会看到每个打印操作的输出 当输出到达终端时立即,而不是当 输出被重定向到一个文件。

print("buz")
fflush(stdout)

您可以强制将输出立即写入文件。 或者,您可以将标准输出设置为行缓冲模式 通过调用

setlinebuf(stdout)

在打印任何内容之前。