1

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:

enter image description here

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.

Community
  • 1
  • 1
esilver
  • 27,713
  • 23
  • 122
  • 168

1 Answers1

0

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."

ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • Thanks so much for this feedback! Hypothetically, let's say at the top of the stack I allocated a huge object, and then called dispatch which launched a long-running thread. Obviously I would want that huge object to be GC'd. The way XCode was presenting me my stack, it made it seem like that might not happen, but per your answer it clearly is. Thanks! – esilver May 22 '15 at 16:21
  • There is no Garbage Collection on iOS, but if ARC would have otherwise deallocated an object when it went out of scope, then that will also have happened here, regardless of the debugging information. – ipmcc May 22 '15 at 16:42
  • RE GC - yes of course -- thanks again for your insight and help!! – esilver May 23 '15 at 17:06