Cocoa Swift无需等待NotificationCenter通知完成即可关闭窗口的实现问题
实现结论
该需求可以直接实现,不需要更换技术方案。
问题根因
默认调用NotificationCenter.default.post(...)是同步执行的:post方法触发后会在当前线程依次执行所有绑定该通知的selector,全部执行完成后post方法才会返回,后续才会执行self.window?.close()逻辑,所以现有写法必然会等待selector执行完成才关闭窗口。
可行实现方式
方式1:异步队列发送通知
将通知发送逻辑放到异步队列执行,调用完发送逻辑后直接触发窗口关闭即可:
// 异步发送通知,不会阻塞当前线程后续执行 DispatchQueue.global().async { NotificationCenter.default.post(name: Notification.Name("frameCaptured"), object: nil) } // 直接关闭窗口,不需要等待通知关联的selector执行完成 self.window?.close()
方式2:使用NotificationQueue异步入队通知
使用系统提供的通知队列做异步入队,无需手动管理队列:
let notify = Notification(name: Notification.Name("frameCaptured")) NotificationQueue.default.enqueue(notify, postingStyle: .asap, coalesceMask: .none, forModes: nil) self.window?.close()
注意事项
- 如果通知关联的selector包含UI操作,需要手动将UI逻辑切回主队列执行,避免出现渲染异常或崩溃
- 如果selector执行需要用到窗口关联的属性,建议提前将需要的值取出作为通知的
object参数传递,避免窗口销毁后出现野指针 - 接收通知的对象如果持有窗口的强引用,建议改为弱引用,避免窗口关闭后无法正常释放内存
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

