NSApp — App状态及其通知

1,836 阅读8分钟

NSApp在状态时会执行的回调方法:(在NSApplication.h文件中)

/* Notifications:
 */
- (void)applicationWillFinishLaunching:(NSNotification *)notification;
- (void)applicationDidFinishLaunching:(NSNotification *)notification;
- (void)applicationWillHide:(NSNotification *)notification;
- (void)applicationDidHide:(NSNotification *)notification;
- (void)applicationWillUnhide:(NSNotification *)notification;
- (void)applicationDidUnhide:(NSNotification *)notification;
- (void)applicationWillBecomeActive:(NSNotification *)notification;
- (void)applicationDidBecomeActive:(NSNotification *)notification;
- (void)applicationWillResignActive:(NSNotification *)notification;
- (void)applicationDidResignActive:(NSNotification *)notification;
- (void)applicationWillUpdate:(NSNotification *)notification;
- (void)applicationDidUpdate:(NSNotification *)notification;
- (void)applicationWillTerminate:(NSNotification *)notification;
- (void)applicationDidChangeScreenParameters:(NSNotification *)notification;
- (void)applicationDidChangeOcclusionState:(NSNotification *)notification API_AVAILABLE(macos(10.9));

对应在‘AppDelegate.Swift’文件中的Swift代码:

//MARK:NSApp的状态
func applicationWillFinishLaunching(_ notification: Notification) { //NSApplication.willFinishLaunchingNotification
    print("applicationWillFinishLaunching \(NSDate() .description)")
    
}
func applicationDidFinishLaunching(_ aNotification: Notification) { //NSApplication.didFinishLaunchingNotification
    // Insert code here to initialize your application
    print("applicationDidFinishLaunching \(NSDate() .description)")
    
}
func applicationWillHide(_ notification: Notification) {    //NSApplication.willHideNotification
    print("applicationWillHide \(NSDate() .description)")
    
}
func applicationDidHide(_ notification: Notification) {     //NSApplication.didHideNotification
    print("applicationDidHide \(NSDate() .description)")
    
}
func applicationWillUnhide(_ notification: Notification) {  //NSApplication.willUnhideNotification
    print("applicationWillUnhide \(NSDate() .description)")
    
}
func applicationDidUnhide(_ notification: Notification) {   //NSApplication.didUnhideNotification
    print("applicationDidUnhide \(NSDate() .description)")
    
}
func applicationWillBecomeActive(_ notification: Notification) {//NSApplication.willBecomeActiveNotification
    print("applicationWillBecomeActive \(NSDate() .description)")
    
}
func applicationDidBecomeActive(_ notification: Notification) { //NSApplication.didBecomeActiveNotification
    print("applicationDidBecomeActive \(NSDate() .description)")
    
}
func applicationWillResignActive(_ notification: Notification) {//NSApplication.willResignActiveNotification
    print("applicationWillResignActive \(NSDate() .description)")
    
}
func applicationDidResignActive(_ notification: Notification) { //NSApplication.didResignActiveNotification
    print("applicationDidResignActive \(NSDate() .description)")
    
}
//func applicationWillUpdate(_ notification: Notification) {  //NSApplication.willUpdateNotification
//    print("applicationWillUpdate \(NSDate() .description)")
// 
// }
// func applicationDidUpdate(_ notification: Notification) {   //NSApplication.didUpdateNotification
//     print("applicationDidUpdate \(NSDate() .description)")
// 
// }
func applicationWillTerminate(_ aNotification: Notification) {  //NSApplication.willTerminateNotification
    // Insert code here to tear down your application
    print("applicationWillTerminate \(NSDate() .description)")
    
}
func applicationDidChangeScreenParameters(_ notification: Notification) {   //NSApplication.didChangeScreenParametersNotification
    print("applicationDidChangeScreenParameters \(NSDate() .description)")
    
}
func applicationDidChangeOcclusionState(_ notification: Notification) { //NSApplication.didChangeOcclusionStateNotification
    print("applicationDidChangeOcclusionState \(NSDate() .description)")
    
}

运行效果:部分可触发状态,会直接响应上述的相应方法

响应的方法: applicationWillFinishLaunchingapplicationDidFinishLaunchingapplicationWillBecomeActiveapplicationDidBecomeActiveapplicationWillResignActiveapplicationDidResignActiveapplicationDidChangeOcclusionStateapplicationDidChangeScreenParameters

若还需要响应 其他特定方法完成 相应操作:(以下举2个例子🌰)

  • 🌰1.让NSApp执行.hide().unhide(),会分别响应applicationWillHide/applicationDidHide回调和 applicationWillUnhide/applicationDidUnhide回调!

书写如下逻辑代码:启动App后,延时5s执行NSApp .hide(nil)来隐藏App,再延时3s执行NSApp .unhide(nil)来取消隐藏App! (不相关的打印代码都注释掉)

//MARK:NSApp的状态
func applicationWillFinishLaunching(_ notification: Notification) { //NSApplication.willFinishLaunchingNotification
    print("applicationWillFinishLaunching \(NSDate() .description)")
    
}
func applicationDidFinishLaunching(_ aNotification: Notification) { //NSApplication.didFinishLaunchingNotification
    // Insert code here to initialize your application
    print("applicationDidFinishLaunching \(NSDate() .description)")
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {//延时5s
        NSApp .hide(nil)    //隐藏App
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3.0) {//延时3s
            NSApp .unhide(nil)//取消隐藏App
        }
    }
}
func applicationWillHide(_ notification: Notification) {    //NSApplication.willHideNotification
    print("applicationWillHide \(NSDate() .description)")
    
}
func applicationDidHide(_ notification: Notification) {     //NSApplication.didHideNotification
    print("applicationDidHide \(NSDate() .description)")
    
}
func applicationWillUnhide(_ notification: Notification) {  //NSApplication.willUnhideNotification
    print("applicationWillUnhide \(NSDate() .description)")
    
}
func applicationDidUnhide(_ notification: Notification) {   //NSApplication.didUnhideNotification
    print("applicationDidUnhide \(NSDate() .description)")
    
}

效果:启动App后,延时5s时隐藏App并打印‘applicationWillHide’、‘applicationDidHide’的信息,再延时3s取消隐藏App并打印‘applicationWillUnhide’、‘applicationDidUnhide’的信息!

  • 🌰2.让NSApp执行.terminate()方法关闭App,会响应applicationWillTerminate方法!

书写如下逻辑代码:启动App后,延时5s执行NSApp .terminate(nil)来关闭App! (不相关的打印代码都注释掉)

//MARK:NSApp的状态
func applicationWillFinishLaunching(_ notification: Notification) { //NSApplication.willFinishLaunchingNotification
    print("applicationWillFinishLaunching \(NSDate() .description)")
    
}
func applicationDidFinishLaunching(_ aNotification: Notification) { //NSApplication.didFinishLaunchingNotification
    // Insert code here to initialize your application
    print("applicationDidFinishLaunching \(NSDate() .description)")
    
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {//延时5s
        print("NSApp .terminate——before \(NSDate() .description)")
        NSApp .terminate(nil)//NSApp (直接)关闭
        print("NSApp .terminate——after \(NSDate() .description)")//‘.terminate’方法之后的代码不会再执行
    }
    
}
func applicationWillTerminate(_ aNotification: Notification) {  //NSApplication.willTerminateNotification
    // Insert code here to tear down your application
    print("applicationWillTerminate \(NSDate() .description)")
    
}

效果:启动App后,延时5s时会关闭App并打印‘applicationWillTerminate’的信息!


NSApp状态对应的通知(Notifications)

窗口(windows)的状态

使用时的代码:在视图控制器(ViewController)中添加App状态相关的通知通知的响应方法,在App的相应状态时以可响应其方法来进行相关操作!

func deleteAllAppStatusNotification() {
    //删除App状态相关的通知
    NotificationCenter .default .removeObserver(self, name: NSApplication.willHideNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didHideNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willUnhideNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didUnhideNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willBecomeActiveNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didBecomeActiveNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willResignActiveNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didResignActiveNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willUpdateNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didUpdateNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willFinishLaunchingNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didFinishLaunchingNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didChangeScreenParametersNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.didChangeOcclusionStateNotification, object: nil)
    NotificationCenter .default .removeObserver(self, name: NSApplication.willTerminateNotification, object: nil)        
}

override func viewWillAppear() {
    super.viewWillAppear()
    
    //添加App状态相关的通知
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillHide), name: NSApplication.willHideNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidHide), name: NSApplication.didHideNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillUnhide), name: NSApplication.willUnhideNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidUnhide), name: NSApplication.didUnhideNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillBecomeActive), name: NSApplication.willBecomeActiveNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidBecomeActive), name: NSApplication.didBecomeActiveNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillResignActive), name: NSApplication.willResignActiveNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidResignActive), name: NSApplication.didResignActiveNotification, object: nil)
    //NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillUpdate), name: NSApplication.willUpdateNotification, object: nil)
    //NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidUpdate), name: NSApplication.didUpdateNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillFinishLaunching), name: NSApplication.willFinishLaunchingNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidFinishLaunching), name: NSApplication.didFinishLaunchingNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidChangeScreenParameters), name: NSApplication.didChangeScreenParametersNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationDidChangeOcclusionState), name: NSApplication.didChangeOcclusionStateNotification, object: nil)
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillTerminate), name: NSApplication.willTerminateNotification, object: nil)
    
}
@objc func notifyApplicationWillHide() {
    print("notifyApplicationWillHide \(NSDate() .description)")
    
}
@objc func notifyApplicationDidHide() {
    print("notifyApplicationDidHide \(NSDate() .description)")
    
}
@objc func notifyApplicationWillUnhide() {
    print("notifyApplicationWillUnhide \(NSDate() .description)")
    
}
@objc func notifyApplicationDidUnhide() {
    print("notifyApplicationDidUnhide \(NSDate() .description)")
    
}
@objc func notifyApplicationWillBecomeActive() {
    print("notifyApplicationWillBecomeActive \(NSDate() .description)")
    
}
@objc func notifyApplicationDidBecomeActive() {
    print("notifyApplicationDidBecomeActive \(NSDate() .description)")
    
}
@objc func notifyApplicationWillResignActive() {
    print("notifyApplicationWillResignActive \(NSDate() .description)")
    
}
@objc func notifyApplicationDidResignActive() {
    print("notifyApplicationDidResignActive \(NSDate() .description)")
    
}
@objc func notifyApplicationWillUpdate() {
    print("notifyApplicationWillUpdate \(NSDate() .description)")
    
}
@objc func notifyApplicationDidUpdate() {
    print("notifyApplicationDidUpdate \(NSDate() .description)")
    
}
@objc func notifyApplicationWillFinishLaunching() {
    print("notifyApplicationWillFinishLaunching \(NSDate() .description)")
    
}
@objc func notifyApplicationDidFinishLaunching() {
    print("notifyApplicationDidFinishLaunching \(NSDate() .description)")
    
}
@objc func notifyApplicationDidChangeScreenParameters() {
    print("notifyApplicationDidChangeScreenParameters \(NSDate() .description)")
    
}
@objc func notifyApplicationDidChangeOcclusionState() {
    print("notifyApplicationDidChangeOcclusionState \(NSDate() .description)")
    
}
@objc func notifyApplicationWillTerminate() {
    print("notifyApplicationWillTerminate \(NSDate() .description)")
    
}

运行效果:

a.部分可触发的状态,会直接响应上述的相应方法!

b.通知对应响应方法打印最后——AppDelegate里面方法回调中的打印出来才执行自己的打印!

Tips:NSApp状态对应注册通知响应方法,执行上是需要AppDelegate里面方法回调执行完毕才会调用! 这点和在iOS中也是一样~

针对:通知对应响应方法打印最后——AppDelegate里面方法回调中的打印出来才执行自己的打印!

如下以**’放弃其活跃状态‘(’WillResignActive‘**)为例子🌰~ 其他状态同理!

验证代码-1:

在‘AppDelegate’里面:(不相关的打印代码都注释掉)

func applicationWillResignActive(_ notification: Notification) {//NSApplication.willResignActiveNotification
    print("applicationWillResignActive \(NSDate() .description)")
    
    print("applicationWillResignActive opreation \(NSDate() .description)")//非延时操作
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.0) {//异步—延时操作
        print("applicationWillResignActive  async delay opreation \(NSDate() .description)")
    }
    print("applicationWillResignActive opreation2 \(NSDate() .description)")//非延时操作
    
    //sleep(2)//阻塞延时2s
    //print("applicationWillResignActive blocked delay opreation3 \(NSDate() .description)")
}

在‘ViewController’中:

override func viewWillAppear() {
    super.viewWillAppear()
    
    //添加App状态相关的通知
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillResignActive), name: NSApplication.willResignActiveNotification, object: nil)
}

@objc func notifyApplicationWillResignActive() {
    print("notifyApplicationWillResignActive \(NSDate() .description)")
    
}

执行效果:‘异步—延时操作’在最后才执行!

验证代码-2:

在‘AppDelegate’里面:(不相关的打印代码都注释掉)

func applicationWillResignActive(_ notification: Notification) {//NSApplication.willResignActiveNotification
    print("applicationWillResignActive \(NSDate() .description)")
    
    print("applicationWillResignActive opreation \(NSDate() .description)")//非延时操作
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.0) {//异步—延时操作
        print("applicationWillResignActive  async delay opreation \(NSDate() .description)")
    }
    print("applicationWillResignActive opreation2 \(NSDate() .description)")//非延时操作
    
    sleep(2)//阻塞延时2s
    print("applicationWillResignActive blocked delay opreation3 \(NSDate() .description)")
}

在‘ViewController’中:

override func viewWillAppear() {
    super.viewWillAppear()
    
    //添加App状态相关的通知
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillResignActive), name: NSApplication.willResignActiveNotification, object: nil)
}

@objc func notifyApplicationWillResignActive() {
    print("notifyApplicationWillResignActive \(NSDate() .description)")
    
}

执行效果:‘异步—延时操作’在最后才执行!‘阻塞延时2s’会影响‘异步—延时操作’!

新需求:快速响应App状态变化

若需要一收到相应状态,就执行对应的操作: 可在‘func applicationWillResignActive(_ notification: Notification)’方法的开头就进行相应操作 — 发送一个自己命名通知,比如‘NSNotification.Name(rawValue: "selfDefine_NSApplication.willResignActiveNotification")’!

在'AppDelegate.swift'中:在applicationWillResignActive方法中的开头,发送自己命名的通知!

func applicationWillResignActive(_ notification: Notification) {
    NotificationCenter .default .post(name: NSNotification.Name(rawValue: "selfDefine_NSApplication.willResignActiveNotification"), object: nil)
    print("start operation! applicationWillResignActive")
    
    print("in operation! applicationWillResignActive")
    
    print("end operation! applicationWillResignActive")
}

在'ViewController.swift'中:添加通知并书写其响应方法~

override func viewWillAppear() {
    super.viewWillAppear()
    //添加App状态相关的通知
    //【一】系统默认的通知
    NotificationCenter .default .addObserver(self, selector: #selector(notifyApplicationWillResignActive), name: NSApplication.willResignActiveNotification, object: nil)
    //【二】自定义的通知
    NotificationCenter .default .addObserver(self, selector: #selector(selfDefine_notifyApplicationWillResignActive), name: NSNotification.Name(rawValue: "selfDefine_NSApplication.willResignActiveNotification"), object: nil)
    
}
@objc func notifyApplicationWillResignActive() {//【一】系统默认的通知
    print("notifyApplicationWillResignActive")
}
@objc func selfDefine_notifyApplicationWillResignActive() {//【二】自定义的通知
    print("selfDefine_notifyApplicationWillResignActive")
}

打印效果:自定义的通知—响应最先执行,而系统默认的通知—最后执行~

selfDefine_notifyApplicationWillResignActive
start operation! applicationWillResignActive
in operation! applicationWillResignActive
end operation! applicationWillResignActive
notifyApplicationWillResignActive


以上便是讨论了NSApp对应的App状态~ 关于macOS系统状态的讨论,请参考《macOS系统的状态切换及其响应方法》!

goyohol's essay