I have an iOS app with which I was previously using performSelectorInBackground to open a persistent socket connection. However, according to this answer, one should never use performSelectorInBackground.
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? Here is what my stack looks like when I call my own internal beginSocketConnection
:
Before, my call to beginSocketConnection
was always (basically) at the top of a very simple stack because it had been invoked by performSelectorInBackground
. That looked nicer/cleaner/better to me, so I'm not sure if this new approach is a bad thing.
First off, I agree with the other answer: Don't use -performSelectorInBackground:withObject:
. Ever.
Next... you said:
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?
Short answer? No. There are no downsides to this.
Long answer:
You appear to be mistaking debugging features for reality. In your screen shot there, those dotted lines aren't "context switches" (for any definition of 'context switch' that I'm aware of.) Xcode is eliding frames from the stack that it believes are not of interest to you (i.e. aren't in your code, or crossing into/out of your code.) You can toggle this behavior with the leftmost control in the bottom bar.
The "Enqueued from" stack traces are historical information aimed at helping you understand what caused the current (i.e. top) stack trace to happen. They're not execution states that still exist. They're just debugging information. You can safely assume that there's no "cost" to you associated with this.
The notion that opening a socket somehow causes a stack to "persist for the lifetime of [your] app" also doesn't make any sense. A socket is just a data structure in memory with some associated behavior provided by the OS. You're thinking about this too much.
Lastly, do yourself a favor, and don't choose APIs based on what makes your debugger stack traces look "nicer/cleaner/better."