使用 GCD 在 iOS 上打开套接字连接是否安全,即使堆栈很复杂?

Is it safe to use GCD to open a socket connection on iOS, even with a complex stack?

我有一个 iOS 应用程序,我之前使用的是 performSelectorInBackground to open a persistent socket connection. However, according to this answer, one should never use performSelectorInBackground

备选方案 GCD and NSOperationQueue 似乎都保留了完整的堆栈框架,包括 4!单独的上下文切换,当我在调试器中暂停我的应用程序时。因此,如果我在特定的深度堆栈中打开套接字连接,该堆栈将在我的应用程序的生命周期内持续存在。

这有什么缺点吗?这是我调用自己的内部 beginSocketConnection:

时堆栈的样子

之前,我对 beginSocketConnection 的调用总是(基本上)在一个非常简单的堆栈的顶部,因为它已被 performSelectorInBackground 调用。我觉得 nicer/cleaner/better,所以我不确定这种新方法是否是坏事。

首先,我同意另一个答案:不要使用 -performSelectorInBackground:withObject:。曾经.

下一个...你说:

The alternative, GCD and NSOperationQueue, both appear to persist the full stack frame, including 4! separate context switches, when I pause my app in the debugger. Therefore, if I open a socket connection inside a particular deep stack, that stack will persist for the lifetime of my app.

Are there any downsides to this?

简答?不会。这没有任何缺点。

长答案:

您似乎将调试功能误认为是现实。在您的屏幕截图中,那些虚线不是 "context switches"(对于我所知道的 'context switch' 的任何定义。)Xcode 正在从它认为是的堆栈中删除帧您不感兴趣(即不在您的代码中,或与您的代码交叉 into/out。)您可以使用底部栏中最左侧的控件切换此行为。

"Enqueued from" 堆栈跟踪是历史信息,旨在帮助您了解导致当前(即顶部)堆栈跟踪发生的原因。它们不是仍然存在的执行状态。它们只是调试信息。您可以放心地假设没有 "cost" 与您相关联。

以某种方式打开套接字会导致堆栈 "persist for the lifetime of [your] app" 的想法也没有任何意义。套接字只是内存中的一种数据结构,具有 OS 提供的一些关联行为。你想太多了。

最后,帮自己一个忙,不要根据调试器堆栈跟踪的外观来选择 API "nicer/cleaner/better."