Could be either, or neither, depending on what exactly self.connection.receive does with the closure you pass to it.
For something like this usually the closure is saved and is called at later time. And thus, despite the appearances, you might not be calling startReceive within itself here.
Swift does support tail call optimizations, but it doesn't make any guarantees. In effect, you could never rely on it, unless you're carefully retesting your code with every compiler version.
The main issue is that functions have a "prelude", a chunk of code that runs after the function body, which makes release calls on any ARC-managed objects used during the function.
So long as your function's last statement is a recursive call (with no extra bells and whistles, like recurse() + [value], recurse() + 1), and your functions doesn't use any ARC--managed objects, then the compiler should be able to tail-call optimize it. But again, don't rely on it.
In any case, the example you show is most certainly not a good dit for recursion. Conceptually it's just messy, but it's also not a candidate for tail call optimization because data and probably contentContext are arc-managed.
Given the context here, the receive(…) method is clearly from NWConnection, you will never recursively call yourself. NWConnection will not call the supplied closure synchronously. Rather, it always dispatches that work to the queue associated with the connection.
It's been my experience in Swift that you should just assume tail-call optimization won't happen. Since trying to actually write code that will trigger that optimization requires deep knowledge of the optimizer and how Swift codegen is done. It also probably requires some deep knowledge of the LLVM optimization passes as well.
eskimo Quinn “The Eskimo!”
June 12
Given the context here, the receive(…) method is clearly from NWConnection, you will never recursively call yourself.
Correct. It is even your code (from some Apple Forum); to be fair though: your code uses a more reasonable value for maximumLength.
NWConnection will not call the supplied closure synchronously. Rather, it always dispatches that work to the queue associated with the connection.
Would be nice if the documentation would mention this.
Regarding the more general question of tail calls: there once was a discussion about "Proposal: Tail Call Optimization keyword/attribute”.
What happened to this idea?