设置NSStreams的正确方法?

时间:2018-12-10 14:09:11

标签: ios bluetooth core-bluetooth nsstream l2cap

我正在编写一个小的点对点蓝牙聊天应用程序。 我目前正在做的是:

let thread = Thread(block: { [weak self] in
    guard let `self` = self else { return }

    self.channel.inputStream.delegate = self
    self.channel.inputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
    self.channel.inputStream.open()

    self.channel.outputStream.delegate = self
    self.channel.outputStream.schedule(in: .current, forMode: .defaultRunLoopMode)
    self.channel.outputStream.open()

    RunLoop.current.run()
})

thread.start()

self.channelCBL2CAPChannel的地方 我目前面临的问题是,它会为每对通道生成新线程,并且最终有太多线程在闲逛。

在这种情况下,设置CBL2CAPChannel的正确方法是什么? Apple的文档为此使用了主线程,这是意外的,并且在有大量连接时可能导致问题。

1 个答案:

答案 0 :(得分:2)

  

Apple的文档为此使用了主线程,这是出乎意料的,并且在存在大量连接时可能导致问题。

这并不意外;这是完全正常的。您不应该为每个流创建单独的线程。运行循环的重点是在不创建新线程的情况下处理并发。在运行循环编程中,很少会创建新线程。运行循环编程早于多核系统而来,它是为协作多任务(而不是抢先式多任务)设计的。

即使您想将事情放到其他内核上,也不要创建Thread对象,除非您正在与需要它的C ++代码进行交互。近十年来,没有太多直接使用NSThread的充分理由。 You pass the work to GCD using DispatchQueue.将数据从流传递到另一个调度队列进行处理是一种非常普通的方法,几乎​​可以将所有工作都移出主队列(然后主队列进行协调)。

如果您有大量的连接,或者它们很忙,那么您可以考虑将它们的全部放在一个单独的线程中(每个连接没有一个线程;总共有一个线程)。但是,按照L2CAP的速率,您不太可能需要这样做。我为G4构建了Mac聊天应用程序,而G4的功能不如具有单线程功能的iPhone 5。