NSAppliaction类
用于管理APP的主时间循环,与APP中所有对象使用的资源。
声明
@MainActor
class
NSApplication
被提及
- Passing control from one app to another with cooperative activation
- Choosing a Specific Appearance for Your macOS App
概览
每个APP都使用一个NSApplication
对象控制主事件循环,保持对APP 窗口和菜单的跟踪,将事件分发给适当的对象(它自己或者它的一个window
),设置自动释放池,接收APP级别事件的通知。一个NSAppliaction
对象有一个代理(一个你指定的对象),当APP打开或关闭,隐藏或唤起,用户选择打开文件等等,都会通知代理。通过设置代理、实现代理方法,你可以自定义APP行为,而不需要子类化NSApplication
.在APP的main()
函数中,通过调用NSApplication
的shared
实例方法,可以创建一个NSApplication
实例。创建application
对象之后,main()
函数应当加载APP的主要nib文件,并通过给application
对象发送run()
消息,来启动事件循环。如果是在Xcode创建的Application对象,main()
函数会自动创建。Xcode创建的main()
函数,开始时会调用NSApplicationMain()
函数,其功能类似如下:
objectivec
void NSApplicationMain(int argc, char *argv[]) {
[NSApplication sharedApplication];
[NSBundle loadNibNamed:@"myMain" owner:NSApp];
[NSApp run];
}
shared
类方法初始化显示环境,并且将你的程序连接到窗口服务器与显示服务器。NSApplication
对象维护一个应用程序使用的所有NSWindow
对象的列表,所以它可以检索任何应用程序的NSView
对象。shared
类方法也会初始化全局变量NSApp
,可以用它来检索NSApplication
实例。shared
只会执行一次。如果调用多次,将会返回之前的对象。
单例NSApplication
对象执行着将从窗口服务器接受事件,分发给适当的NSResponder
的重要任务。NSApp
将事件转换为NSEvent
对象,然后将事件对象转发给受影响的NSWindow
对象。所有键盘和鼠标事件都直接转到与事件关联的NSWindow对象。这条规则的唯一例外是,当key-down
事件触发时,Command
键被按下;在这种情况下,每个NSWindow
都有机会响应事件。当一个窗口对象从NSApp
接收到一个NSEvent
对象时,它会把它分发给它的视图层次中的对象。
NSApplication
还负责分派APP接收到的某些Apple事件。例如:macOS在不同时间向你的APP发送Apple事件,如APP打开或关闭。NSApplicatio
安装Apple事件处理程序,通过向适当的对象发送消息来处理这些事件。你也可以用NSAppleEventManager
类来注册你自己的Apple事件处理程序。在applicationWillFinishLaunching(_:)
最适合做这种事情。有关如何处理事件以及如何修改默认行为的更多信息,包括在可脚本应用程序中使用Apple事件的信息,详见:How Cocoa Applications Handle Apple Events在Cocoa Scripting Guide中。
NSApplication
类在初始化和事件循环中设置@autorelease
块,具体来说是在初始化(或者shared
)和run()
方法中。类似地,AppKit添加到Bundle
的方法在加载nib文件时也会使用@autorelease
块。这些@autorelease
块在各自的NSApplication
和Bundle
方法的作用域之外是不可访问的。通常情况下,APP要么是在事件循环运行时创建,要么是从nib文件中加载,所以通常不会有访问权限的问题。然而,如果你确实需要在main()
函数本身中使用Cocoa
类(而不是加载nib文件或实例化NSApplication
),你应该创建一个@autorelease
块来包含使用这些类的代码。
代理和通知
你可以给你的NSApplication
对象指定一个代理,代理代表NSApplication
对象响应某些消息。类似的消息如:application(_:openFile:)
,要求代理执行某个操作;applicationShouldTerminate( _ : )
,由代理决定是否允许APP退出。NSApplication
类将这些消息直接发送给它的代理。
NSApplication
同样会给APP的默认通知中心发送通知。任何对象都可以通过发送消息addObserver( _ :selector:name:object:)
到默认的通知中心(NSNotificationCenter
类的一个实例)来注册接收NSApplication
发出的一个或多个通知。NSApplication
的代理如果实现了某些代理方法,会自动注册并接收通知。例如,NSApplication
在即将完成启动应用程序和完成启动应用程序时发布通知(willFinishLaunchingNotification
和didFinishLaunchingNotification
)。代理可以通过实现方法applicationWillFinishLaunching( _ :)
和applicationDidFinishLaunching( _ :)
来响应这些通知。如果代理想知道这两个事件,就实现这两个方法,如果只需要知道APP何时加载完成,只需要实现applicationDidFinishLaunching( _ :)
就可以。
系统服务
NSApplication
与系统服务架构交互,通过services
菜单为你的应用提供服务。
关于继承
很少有需要子类化NSApplication
的情况。不像其他面向对象的库,Cocoa不需要继承NSApplication
来实现自定义APP行为。而是提供很多其他方式来自定义APP。本节将讨论有可能需要子类化NSApplication
的原因,和不需要子类化NSApplication
的原因。