NSApplication

Class NSApplication

  • 管理应用程序的主要事件循环和所有应用程序对象使用的资源对象;
概述:

每个应用程序使用一个 NSApplication 实例来控制主事件循环,跟踪应用程序的窗口和菜单,将事件分发到适当的对象(即本身或者其中的一个窗口),设置自动释放池,并接受应用级事件的通知. NSApplication 对象有一个委托(程序员分配的对象),当应用程序启动或终止,被隐藏或者激活时,应该打开用户选择的文件,等等.通过设置代理(delegate)和实现代理方法,程序员可以自定义程序的行为,而无需再次子类话 NSApplication. 在应用程序的 main() 函数中,通过调用 NSApplication 的 sharedApplication 方法来创建 NSApplication 的实例.创建应用程序对象后,在 main() 函数中应该加载应用程序的主 nib 文件,然后通过发应用程序对象的 run 信息来启动循环事件.如果在 Xcode 中创建一个应用程序项目, 那么这个 main() 函数是已经为程序员创建好的. main () 函数Xcode 的创建调用名为 NSApplicationMain() 的函数, 其功能类似于一下内容:

void NSAppilcationMain (int argc, char *argv[]) {
    [NSApplication sharedApplication];
    [NSBundle loadNibNamed:@"myMain" owner NSApp];
    [NSApp run]; 
}

sharedApplication 类方法初始化显示环境, 并将应用程序连接到窗口服务器和显示服务器. NSApplication 对象维护 app 使用列表中的所有NSWindow对象. 因此它可以检索任何应用程序的NSView对象. sharedApplication 方法还初始化全局变量的NSApp.程序员可以使用它来检索NSApplication实例. sharedApplication 只执行一次初始化;如果你多次调用它,它只会返回之前所创建的对象.

共享的 NSApplication 对象执行从窗口服务器接收事件并将其分发到正确的重要任务 NSResponder 类. NSApp 将事件翻译成 NSEvent 对象, 然后将事件对象转发到受影响的NSWindow对象.所有的键盘和鼠标事件都直接转到与事件关联的NSWindow对象. 该规则的唯一例外是如果法伤按键事件时按下Command键; 在这种情况下,每个 NSWindow 对象都有机会响应事件. 当窗口对象从 NSApp 接收到 NSEvent 对象时, 它将其分发到对应视图层次结构中的对象.

NSApplication 也负责派发应用程序收到的某些 Apple 事件. 例如, macOS 会再不同时间将 Apple 事件发送到应用程序, 例如应用程序启动或者重新打开时. NSApplication 通过向适当的对象发送消息来安装 Apple 事件处理程序(Apple event handlers)来处理这些事件. 也可以使用 NSAppleEventManager 类来注册自己的 Apple 事件操作者 (Apple event handlers). 通常最好在
applicationWillFinishLaunching: 方法中去做这些事情.

NSApplication 类在初始化期间和事件循环内设置@autorelease block , 特别是在其初始化期间 (或者 sharedApplication)和 run 方法. 类似的, AppKit 添加 NSBundle 的方法在加载 nib 文件期间使用@autorelease blocks. 在这些@ autorelease blocks 块在相应的范围之外是不可访问 NSApplication 和 NSBundle 的方法的. 通常, app 在事件循环正在运行或通过从 nib 文件中加载对象时创建对象, 因此缺乏访问(不能访问)基本不是问题. 但是,如果确实需要在 main() 函数中使用 cocoa 类(加载 nib 文件或者实例化 NSApplication 之外),则应该创建一个@autorelease blocks 以包含使用该类代码.

代理和通知

你可以为 NSApplication 对象指定 delegate, 这个 delegate 代表对象回应某些特定的消息. 其中的一些信息例如: application(:openFile:),请求 delegate 执行一个动作. 另一个消息, applicationShouldTerminate(:),让 delegate 确认允许应用程序退出. NSApplication 类将这些消息直接发送给 delegate.

NSApplication 还会将通知发送到应用的默认通知中心. 任何对象可以通过 addObserver (:selector:name:object:) 方法注册一个监听事件到默认通知中心(NSNotifiactionCenter 类的一个实例),来接收 NSApplication 发布的一个或者多个通知. 如果 NSApplication 的的 delegate 实现了某些委托方法,则会自动注册 NSApplication 的代理接收这些通知.例如: NSApplication 将在即将完成启动应用程序以及启动应用程序时发布通知(willFinishLaunchingNotification 和 didFinishLaunchingNotification). delegate 有机会响应这些通知,通过实施这些方法: applicationWillFinishLaunching(:) 和 applicationDidFinishLaunching(:). 如果 delegate 想要通知这两个事件, 它必须实现这两种方法. 如果只需要知道应用程序的启动完成,那么只需要实现 applicationDidFinishLaunching(:)的方法可以了.

系统服务

NSApplication 于系统服务架构进行交互, 通过"服务"菜单为应用程序提供服务.

子类注释(NSApplication)

你会发现,很少需要去创建一个自定义的 NSApplication 的子类.与某些面向对象的库不同, Cocoa 不要求将 NSApplication 子类化以自定义应用程序的行为. 相反,它为程序员提供了许多其他方式来自定义应用程序.本节讨论 NSApplication 子类化的一些可能原因, 以及不将 NSApplication 进行子类化的一些原因.

要使用 NSApplication 自定义子类,只要发送共享到你的子类而不是直接到 NSApplication. 如果在 Xcode 中创建应用程序, 可以通过将自定义应用程序类设置为主类来实现. 在 Xcode 中,双击"Groups and Files "列表中的应用程序目标, 以打开目标的 "Info" 窗口. 然后显示窗口的 "Properties" 窗格,并使用自定义类的名称在 "Principal Class " 中替换 "NSApplication" . NSApplicationMain 函数发送共享到主类获取全局应用程序实例(NSApp) - 在这种情况下, 这将是程序员自定义 NSApplication 子类的一个实例.

重要:
许多 AppKit 类依赖于 NSApplication 类, 并且在该类完全初始化之前可能无法正常工作. 因此,不应该尝试从 NSApplication 子类的初始化方法里调用其他 AppKit 类的方法.

覆盖方法

通常, 程序员习惯性的在向全局应用对象(NSApp)发送消息时, 提供或者实现自有的特殊方法. 这时,可以在 NSApplication 子类化里覆盖原始方法来实现. 以下是候选的4中覆盖方法:

  • 覆盖(Override) run() ---- 如果你希望应用程序不是以默认的方式启动管理主事件的循环.(这是一个关键和复杂的任务, 但是, 有理由尝试).
  • 覆盖(Override) sendEvent(_:) ---- 如果要更改事件的调度方式或者执行一些特殊的事件处理.
  • 覆盖(Override) requestUserAttention(_:) ---- 如果想修改应用程序如何吸引用户注意力(例如,提供一个代替的弹跳应用程序图标在 Dock).
  • 覆盖(Override) target(forAction:) ---- 为 target 的动作消息替换另一个对象.
特别注意事项

全局应用对象在其使用@autorelease blocks 在它的 run()方法; 如果你需要覆盖(Override)此方法,则血药创建自己的@autorelease blocks. 不要覆盖sharedApplication 方法.app 默认的必要行为太过于复杂以至于无法在程序员自定义的方法中复制.

子类化的替代方法

NSApplication 定义了许多 delegate 方法, 这些 delegate 方法提供了修改应用程序某些特定行为的机会. app delegate 能够执行1个或者多个这些方法以达成你的设计目的. 一般来说, 比子类化更好的设计 NSApplication 是将应用程序的特殊行为表达的代码放入一个或者多个自定义对象的控制器中. 控制器中定义的方法可以从一个小的调度器对象调用, 而不会与全局应用程序对象紧密相连.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,118评论 29 470
  • 转:http://www.cocoachina.com/programmer/20151019/13746.htm...
    Style_伟阅读 1,289评论 0 3
  • 1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是...
    Charls丶阅读 743评论 0 0
  • 材料:大米,糯米,胡萝卜,黄瓜,巧克力,椰子碎。 把煮熟的米饭攥成团。三到五个。然后在巧克力碎和椰子碎里滚一滚。
    Karlina简称K阅读 129评论 0 0