Hi,
I’m using Network Framework to implement a UDP listener via NWListener. I am looking for clarification about the correct and fully safe shutdown procedure, especially regarding resource release.
After calling listener.cancel(), do we need to wait for the .cancelled state before exiting the application? Or can we just exit once the cancellation is initiated, assuming the OS will close the NWListener and there will be no resource leak?
Is it recommended (or required) to set newConnectionHandler = nil when shutting down a UDP listener? My understanding is that if there is no NWListener attached, then whenever a connection is accepted by the OS, it will not be delivered to the application and the OS will simply drop it.
There are two parts to this:
- How to cleanly close an
NWListenerin general. - And what to do when “exiting the application”.
After calling listener.cancel(), do we need to wait for the .cancelled state … ?
No.
From the perspective of Network framework, the cancellation will proceed asynchronously and that’s just fine. However, it’s easy to think of cases where you might need to do that due to considerations in your code. Imagine, for example, that you have a listener controlled by a Start / Stop button. If the user clicks Stop and then immediately clicks Start, bad things might happen if the cancellation is still in progress. In that case, you’d want to show a status of stopping and not enable the Start button until the cancellation is complete.
Is it recommended (or required) to set newConnectionHandler = nil when shutting down a UDP listener?
It shouldn’t be required, but it’s something I generally do.
The framework was designed such that you shouldn’t need to do this. However, there was a historical bug where failing to do this could create retain loops that weren’t broken by you cancelling the listener. Therefore, I generally do nil out any handlers before cancelling.
I’m not 100% when we fixed this bug, but I’m quite sure it’s fixed in the macOS 26 and friends.
Coming back to the second point, you wrote:
before exiting the application?
Apple platforms track resources on a process-by-process basis. If your process terminates, all the resources it uses are cleaned up by the OS. That includes any memory or network resources used by NWListener. So, if your process is in a state where it will shortly terminate, there’s no reason to clean up your listener at all. You can just let the process terminate and the system will clean up.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"