NSApplication

Class NSApplication

  • 管理應(yīng)用程序的主要事件循環(huán)和所有應(yīng)用程序?qū)ο笫褂玫馁Y源對(duì)象;
概述:

每個(gè)應(yīng)用程序使用一個(gè) NSApplication 實(shí)例來(lái)控制主事件循環(huán),跟蹤應(yīng)用程序的窗口和菜單,將事件分發(fā)到適當(dāng)?shù)膶?duì)象(即本身或者其中的一個(gè)窗口),設(shè)置自動(dòng)釋放池,并接受應(yīng)用級(jí)事件的通知. NSApplication 對(duì)象有一個(gè)委托(程序員分配的對(duì)象),當(dāng)應(yīng)用程序啟動(dòng)或終止,被隱藏或者激活時(shí),應(yīng)該打開(kāi)用戶選擇的文件,等等.通過(guò)設(shè)置代理(delegate)和實(shí)現(xiàn)代理方法,程序員可以自定義程序的行為,而無(wú)需再次子類話 NSApplication. 在應(yīng)用程序的 main() 函數(shù)中,通過(guò)調(diào)用 NSApplication 的 sharedApplication 方法來(lái)創(chuàng)建 NSApplication 的實(shí)例.創(chuàng)建應(yīng)用程序?qū)ο蠛?在 main() 函數(shù)中應(yīng)該加載應(yīng)用程序的主 nib 文件,然后通過(guò)發(fā)應(yīng)用程序?qū)ο蟮?run 信息來(lái)啟動(dòng)循環(huán)事件.如果在 Xcode 中創(chuàng)建一個(gè)應(yīng)用程序項(xiàng)目, 那么這個(gè) main() 函數(shù)是已經(jīng)為程序員創(chuàng)建好的. main () 函數(shù)Xcode 的創(chuàng)建調(diào)用名為 NSApplicationMain() 的函數(shù), 其功能類似于一下內(nèi)容:

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

sharedApplication 類方法初始化顯示環(huán)境, 并將應(yīng)用程序連接到窗口服務(wù)器和顯示服務(wù)器. NSApplication 對(duì)象維護(hù) app 使用列表中的所有NSWindow對(duì)象. 因此它可以檢索任何應(yīng)用程序的NSView對(duì)象. sharedApplication 方法還初始化全局變量的NSApp.程序員可以使用它來(lái)檢索NSApplication實(shí)例. sharedApplication 只執(zhí)行一次初始化;如果你多次調(diào)用它,它只會(huì)返回之前所創(chuàng)建的對(duì)象.

共享的 NSApplication 對(duì)象執(zhí)行從窗口服務(wù)器接收事件并將其分發(fā)到正確的重要任務(wù) NSResponder 類. NSApp 將事件翻譯成 NSEvent 對(duì)象, 然后將事件對(duì)象轉(zhuǎn)發(fā)到受影響的NSWindow對(duì)象.所有的鍵盤和鼠標(biāo)事件都直接轉(zhuǎn)到與事件關(guān)聯(lián)的NSWindow對(duì)象. 該規(guī)則的唯一例外是如果法傷按鍵事件時(shí)按下Command鍵; 在這種情況下,每個(gè) NSWindow 對(duì)象都有機(jī)會(huì)響應(yīng)事件. 當(dāng)窗口對(duì)象從 NSApp 接收到 NSEvent 對(duì)象時(shí), 它將其分發(fā)到對(duì)應(yīng)視圖層次結(jié)構(gòu)中的對(duì)象.

NSApplication 也負(fù)責(zé)派發(fā)應(yīng)用程序收到的某些 Apple 事件. 例如, macOS 會(huì)再不同時(shí)間將 Apple 事件發(fā)送到應(yīng)用程序, 例如應(yīng)用程序啟動(dòng)或者重新打開(kāi)時(shí). NSApplication 通過(guò)向適當(dāng)?shù)膶?duì)象發(fā)送消息來(lái)安裝 Apple 事件處理程序(Apple event handlers)來(lái)處理這些事件. 也可以使用 NSAppleEventManager 類來(lái)注冊(cè)自己的 Apple 事件操作者 (Apple event handlers). 通常最好在
applicationWillFinishLaunching: 方法中去做這些事情.

NSApplication 類在初始化期間和事件循環(huán)內(nèi)設(shè)置@autorelease block , 特別是在其初始化期間 (或者 sharedApplication)和 run 方法. 類似的, AppKit 添加 NSBundle 的方法在加載 nib 文件期間使用@autorelease blocks. 在這些@ autorelease blocks 塊在相應(yīng)的范圍之外是不可訪問(wèn) NSApplication 和 NSBundle 的方法的. 通常, app 在事件循環(huán)正在運(yùn)行或通過(guò)從 nib 文件中加載對(duì)象時(shí)創(chuàng)建對(duì)象, 因此缺乏訪問(wèn)(不能訪問(wèn))基本不是問(wèn)題. 但是,如果確實(shí)需要在 main() 函數(shù)中使用 cocoa 類(加載 nib 文件或者實(shí)例化 NSApplication 之外),則應(yīng)該創(chuàng)建一個(gè)@autorelease blocks 以包含使用該類代碼.

代理和通知

你可以為 NSApplication 對(duì)象指定 delegate, 這個(gè) delegate 代表對(duì)象回應(yīng)某些特定的消息. 其中的一些信息例如: application(:openFile:),請(qǐng)求 delegate 執(zhí)行一個(gè)動(dòng)作. 另一個(gè)消息, applicationShouldTerminate(:),讓 delegate 確認(rèn)允許應(yīng)用程序退出. NSApplication 類將這些消息直接發(fā)送給 delegate.

NSApplication 還會(huì)將通知發(fā)送到應(yīng)用的默認(rèn)通知中心. 任何對(duì)象可以通過(guò) addObserver (:selector:name:object:) 方法注冊(cè)一個(gè)監(jiān)聽(tīng)事件到默認(rèn)通知中心(NSNotifiactionCenter 類的一個(gè)實(shí)例),來(lái)接收 NSApplication 發(fā)布的一個(gè)或者多個(gè)通知. 如果 NSApplication 的的 delegate 實(shí)現(xiàn)了某些委托方法,則會(huì)自動(dòng)注冊(cè) NSApplication 的代理接收這些通知.例如: NSApplication 將在即將完成啟動(dòng)應(yīng)用程序以及啟動(dòng)應(yīng)用程序時(shí)發(fā)布通知(willFinishLaunchingNotification 和 didFinishLaunchingNotification). delegate 有機(jī)會(huì)響應(yīng)這些通知,通過(guò)實(shí)施這些方法: applicationWillFinishLaunching(:) 和 applicationDidFinishLaunching(:). 如果 delegate 想要通知這兩個(gè)事件, 它必須實(shí)現(xiàn)這兩種方法. 如果只需要知道應(yīng)用程序的啟動(dòng)完成,那么只需要實(shí)現(xiàn) applicationDidFinishLaunching(:)的方法可以了.

系統(tǒng)服務(wù)

NSApplication 于系統(tǒng)服務(wù)架構(gòu)進(jìn)行交互, 通過(guò)"服務(wù)"菜單為應(yīng)用程序提供服務(wù).

子類注釋(NSApplication)

你會(huì)發(fā)現(xiàn),很少需要去創(chuàng)建一個(gè)自定義的 NSApplication 的子類.與某些面向?qū)ο蟮膸?kù)不同, Cocoa 不要求將 NSApplication 子類化以自定義應(yīng)用程序的行為. 相反,它為程序員提供了許多其他方式來(lái)自定義應(yīng)用程序.本節(jié)討論 NSApplication 子類化的一些可能原因, 以及不將 NSApplication 進(jìn)行子類化的一些原因.

要使用 NSApplication 自定義子類,只要發(fā)送共享到你的子類而不是直接到 NSApplication. 如果在 Xcode 中創(chuàng)建應(yīng)用程序, 可以通過(guò)將自定義應(yīng)用程序類設(shè)置為主類來(lái)實(shí)現(xiàn). 在 Xcode 中,雙擊"Groups and Files "列表中的應(yīng)用程序目標(biāo), 以打開(kāi)目標(biāo)的 "Info" 窗口. 然后顯示窗口的 "Properties" 窗格,并使用自定義類的名稱在 "Principal Class " 中替換 "NSApplication" . NSApplicationMain 函數(shù)發(fā)送共享到主類獲取全局應(yīng)用程序?qū)嵗?NSApp) - 在這種情況下, 這將是程序員自定義 NSApplication 子類的一個(gè)實(shí)例.

重要:
許多 AppKit 類依賴于 NSApplication 類, 并且在該類完全初始化之前可能無(wú)法正常工作. 因此,不應(yīng)該嘗試從 NSApplication 子類的初始化方法里調(diào)用其他 AppKit 類的方法.

覆蓋方法

通常, 程序員習(xí)慣性的在向全局應(yīng)用對(duì)象(NSApp)發(fā)送消息時(shí), 提供或者實(shí)現(xiàn)自有的特殊方法. 這時(shí),可以在 NSApplication 子類化里覆蓋原始方法來(lái)實(shí)現(xiàn). 以下是候選的4中覆蓋方法:

  • 覆蓋(Override) run() ---- 如果你希望應(yīng)用程序不是以默認(rèn)的方式啟動(dòng)管理主事件的循環(huán).(這是一個(gè)關(guān)鍵和復(fù)雜的任務(wù), 但是, 有理由嘗試).
  • 覆蓋(Override) sendEvent(_:) ---- 如果要更改事件的調(diào)度方式或者執(zhí)行一些特殊的事件處理.
  • 覆蓋(Override) requestUserAttention(_:) ---- 如果想修改應(yīng)用程序如何吸引用戶注意力(例如,提供一個(gè)代替的彈跳應(yīng)用程序圖標(biāo)在 Dock).
  • 覆蓋(Override) target(forAction:) ---- 為 target 的動(dòng)作消息替換另一個(gè)對(duì)象.
特別注意事項(xiàng)

全局應(yīng)用對(duì)象在其使用@autorelease blocks 在它的 run()方法; 如果你需要覆蓋(Override)此方法,則血藥創(chuàng)建自己的@autorelease blocks. 不要覆蓋sharedApplication 方法.app 默認(rèn)的必要行為太過(guò)于復(fù)雜以至于無(wú)法在程序員自定義的方法中復(fù)制.

子類化的替代方法

NSApplication 定義了許多 delegate 方法, 這些 delegate 方法提供了修改應(yīng)用程序某些特定行為的機(jī)會(huì). app delegate 能夠執(zhí)行1個(gè)或者多個(gè)這些方法以達(dá)成你的設(shè)計(jì)目的. 一般來(lái)說(shuō), 比子類化更好的設(shè)計(jì) NSApplication 是將應(yīng)用程序的特殊行為表達(dá)的代碼放入一個(gè)或者多個(gè)自定義對(duì)象的控制器中. 控制器中定義的方法可以從一個(gè)小的調(diào)度器對(duì)象調(diào)用, 而不會(huì)與全局應(yīng)用程序?qū)ο缶o密相連.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評(píng)論 19 139
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,660評(píng)論 30 472
  • 轉(zhuǎn):http://www.cocoachina.com/programmer/20151019/13746.htm...
    Style_偉閱讀 1,478評(píng)論 0 3
  • 1. Object-c的類可以多重繼承么?可以實(shí)現(xiàn)多個(gè)接口么?Category是什么?重寫一個(gè)類的方式用繼承好還是...
    Charls丶閱讀 794評(píng)論 0 0
  • 材料:大米,糯米,胡蘿卜,黃瓜,巧克力,椰子碎。 把煮熟的米飯攥成團(tuán)。三到五個(gè)。然后在巧克力碎和椰子碎里滾一滾。
    Karlina簡(jiǎn)稱K閱讀 203評(píng)論 0 0

友情鏈接更多精彩內(nèi)容