Cocoa如何應用設計模式
Cocoa經常把自己與眾不同的工作機制建立在模式上,它的設計受到諸如語言能力或現有架構這樣因素的影響。本部分包含設計模式:可重用的面向對象軟件的元素壹書中編目的大多數設計模式的介紹。每個設計模式都有壹個總結性的描述,以及該模式的Cocoa實現的討論。文中列出的都是Cocoa實現的模式,每個模式的討論都發生在特定的Cocoa環境中。我們推薦您熟悉這些模式,您會發現這些模式在Cocoa軟件開發中非常有用。Cocoa中設計模式的實現有不同的形式。下面部分中描述的壹些設計—比如協議和範疇—是Objective-C語言的特性;在另外壹些場合中,“模式的實例”被實現為壹個類或壹組相關的類(比如類簇和單件類);還有壹些場合下,模式表現為壹個大的框架結構,比如響應者鏈模式。對於某些基於模式的機制,您幾乎可以“免費”使用;而另外壹些機制則要求您做壹些工作。即使對於Cocoa沒有實現的模式,我們也鼓勵您在條件許可的情況下自行實現,比如在擴展類的行為時,對象合成(裝飾模式)技術通常就比生成子類更好。有兩個設計模式沒有在下面的內容中進行討論,即模型-視圖-控制器(MVC)模式和對象建模。MVC是壹種復合或聚合模式,就是說它基於幾種不同類型的模式。對象建模在四人組的分類目錄中沒有對應類別,它源自關系數據庫領域。然而,MVC和對象建模在Cocoa中可能是最重要和最普遍的設計模式或用語,而且它們在很大程度上是相關的。它們在幾個技術的設計中發揮關鍵的作用,包括綁定、撤消管理、腳本控制、和文檔架構。要了解更多有關這些模式的信息,請參見"模型-視圖-控制器設計模式"和"對象建模"部分。本部分包含如下主要內容:抽象工廠模式適配器模式責任鏈模式命令模式合成模式裝飾模式表觀模式跌代器模式仲裁者模式備忘錄模式觀察者模式代理模式單件模式模板方法模式抽象工廠模式提供壹個接口,用於創建與某些對象相關或依賴於某些對象的類家族,而又不需要指定它們的具體類。通過這種模式可以去除客戶代碼和來自工廠的具體對象細節之間的耦合關系。類簇類簇是壹種把壹個公***的抽象超類下的壹些私有的具體子類組合在壹起的架構。抽象超類負責聲明創建私有子類實例的方法,會根據被調用方法的不同分配恰當的具體子類,每個返回的對象都可能屬於不同的私有子類。Cocoa將類簇限制在數據存儲可能因環境而變的對象生成上。Foundation框架為NSString、NSData、NSDictionary、NSSet、和NSArray對象定義了類簇。公***超類包括上述的不可變類和與其相互補充的可變類NSMutableString、NSMutableData、NSMutableDictionary、NSMutableSet、和NSMutableArray。使用和限制當您希望創建類簇代表的類型的可變或不可變對象時,可以使用類簇中的某個公***類來實現。使用類簇是在簡潔性和擴展性之間進行折衷。類簇可以簡化類接口,因此使其更易於學習和使用,但是創建類簇抽象類的定制子類則會變得更加困難。進壹步閱讀: "類簇" 部分提供有關Cocoa類簇的更多信息。 適配器模式將壹個類接口轉化為客戶代碼需要的另壹個接口。適配器使原本由於兼容性而不能協同工作的類可以工作在壹起,消除了客戶代碼和目標對象的類之間的耦合性。協議協議是壹個編程語言級別(Objective-C)的特性,它使定義適配器模式的實例成為可能(在 Java中的“接口”和“協議”是同義的)。如果您希望壹個客戶對象和另壹個對象進行交流,但由於它們的接口不兼容而導致困難,您就可以定義壹個協議,它本質上是壹系列和類不相關聯的方法聲明。這樣,其它對象的類就可以正式采納該協議,並通過實現協議中的全部方法來“遵循”該協議。結果,客戶對象就可以通過協議接口向其它對象發送消息。協議是壹組獨立於類層次的方法聲明,這樣就有可能象類的繼承那樣,根據對象遵循的協議對其進行分組。您可以通過NSObject的conformsToProtocol:方法來確認壹個對象的協議關系。除了正式協議之外,Cocoa還有壹個非正式協議的概念。這種類型的協議是NSObject類中的壹個範疇(category),這樣就使所有的對象都成為範疇方法的潛在實現者(參見"範疇"部分)。非正式協議的方法可以選擇性地實現。非正式協議是委托機制實現的壹部分(參見"委托"部分。請註意,協議的設計和適配器模式並不完全匹配。但它是使接口不兼容的類在得以協同工作的手段。使用和限制協議主要用於聲明層次結構上不相關的類為了互相通訊而需要遵循的接口。但是,您也可以將協議用於聲明對象的接口,而隱藏相應的類。Cocoa框架包括很多正式協議,這些協議使定制子類可以和框架進行特定目的的通訊。舉例來說,Foundation框架中包含NSObject、NSCopying、和NSCoding協議,都非常重要。Application Kit中的協議包括NSDraggingInfo、NSTextInput、和NSChangeSpelling。正式協議要求遵循者實現協議聲明的所有方法。它們也是零碎的,壹旦您定義壹個協議並將它提供給其它類,將來對協議的修改會使那些類不能工作。進壹步閱讀:有關正式協議的更多信息請參見Objective-C編程語言文檔中“擴展類”部分的討論。 責任鏈模式通過為多個對象提供處理請求的機會,避免請求的發送者和接收者產生耦合。將接收對象串成鏈,並將請求沿著接收者鏈進行傳遞,直到某個對象對其進行處理。對象或者處理該請求,或者將它傳遞給鏈中的下壹個對象。響應者鏈Application Kit框架中包含壹個稱為響應者鏈的架構。該鏈由壹系列響應者對象(就是從NSResponder繼承下來的對象)組成,事件(比如鼠標點擊)或者動作消息沿著鏈進行傳遞並(通常情況下)最終被處理。如果給定的響應者對象不處理特定的消息,就將消息傳遞給鏈中的下壹個響應者。響應者在鏈中的順序通常由視圖的層次結構來決定,從層次較低的響應者對象向層次較高的對象傳遞,頂點是管理視圖層次結構的窗口對象,窗口對象的委托對象,或者全局的應用程序對象。事件和動作消息在響應者鏈中的確切傳遞路徑是不盡相同的。壹個應用程序擁有的響應者鏈可能和它擁有的窗口(甚至是局部層次結構中的視圖對象)壹樣多,但每次只能有壹個響應者鏈是活動的—也就是與當前活動窗口相關聯的那個響應鏈。還有壹個與響應者鏈相類似的鏈,用於應用程序的錯誤處理。視圖層次的設計應用的是合成模式(參見"合成模式"部分),它和響應者鏈密切相關。動作消息—源自控件對象的消息—基於目標-動作機制,是命令模式(參見"命令模式"部分)的壹個實例。使用和限制當您通過Interface Builder或以編程的方式為程序構造用戶界面時,可以“免費”得到壹個或多個響應者鏈。響應者鏈和視圖層次結構壹起出現,當您使壹個視圖對象成為窗口內容視圖的子視圖時,視圖層次結構就自動生成了。如果您將壹個定制視圖加入到壹個視圖層次結構中,它就變成響應者鏈的壹部分;如果您實現了恰當的NSResponder方法,就可以接收和處理事件及動作消息。定制對象是窗口對象或全局應用程序對象NSApp的委托對象,也可以接收和處理那些消息。您也可以用編程的方式將定制的響應者對象註入到響應者鏈中,以及通過編程操作響應者在鏈中的順序。進壹步閱讀: 處理事件和動作消息及程序錯誤的的響應者鏈在Cocoa事件處理指南和Cocoa的錯誤處理編程指南文檔中進行描述。本文檔在"合成模式"部分對視圖層次結構有總結性的介紹,在"核心應用程序架構"部分有更全面的描述。 命令模式這種模式將請求封裝為對象,使您可以用不同的請求來對客戶代碼進行參數化;對請求進行排隊和記錄,並支持可撤消(undoable)的操作。請求對象將壹或多個動作綁定在特定的接收者上。命令模式將發出請求的對象和接收及執行請求的對象區分開來。調用對象NSInvocation類的實例用於封裝Objective-C消息。壹個調用對象中含有壹個目標對象、壹個方法選擇器、以及方法參數。您可以動態地改變調用對象中消息的目標及其參數,壹旦消息被執行,您就可以從該對象得到返回值。通過壹個調用對象可以多次調用目標或參數不同的消息。創建NSInvocation對象需要使用NSMethodSignature對象,該對象負責封裝與方法參數和返回值有關系的信息。NSMethodSignature對象的創建又需要用到壹個方法選擇器。NSInvocation的實現還用到Objective-C運行環境的壹些函數。使用和限制NSInvocation對象是分布式、撤消管理、消息傳遞、和定時器對象編程接口的壹部分。在需要去除消息發送對象和接收對象之間的耦合關系的類似場合下,您也可以使用。分布式對象是壹種進程間通訊技術,關於這個主題的更多信息請參見"代理模式"部分。進壹步閱讀:調用對象的細節請閱讀NSInvocation的類參考文檔。您也可以從下面的文檔中獲取相關技術的信息:Objective-C編程語言文檔中的分布式對象、撤消架構、定時器以及之後的部分。 目標-動作目標-動作機制使控件對象—也就是象按鍵或文本輸入框這樣的對象—可以將消息發送給另壹個可以對消息進行解釋並將它處理為具體應用程序指令的對象。接收對象,或者說是目標,通常是壹個定制的控制器對象。消息—也被稱為動作消息—由壹個選擇器來確定,選擇器是壹個方法的唯壹運行時標識。典型情況下,控件擁有的單元對象會對目標和動作進行封裝,以便在用戶點擊或激活控件時發送消息(菜單項也封裝了目標和動作,以便在用戶選擇時發送動作消息)。目標-動作機制之所以能夠基於選擇器(而不是方法簽名),是因為Cocoa規定動作方法的簽名和選擇器名稱總是壹樣的。使用和限制當您用Interface Builder構建程序的用戶界面時,可以對控件的動作和目標進行設置。您因此可以讓控件具有定制的行為,而又不必為控件本身書寫任何的代碼。動作選擇器和目標連接被歸檔在nib文件中,並在nib文件被解檔時復活。您也可以通過向控件或它的單元對象發送setTarget:和setAction:消息來動態地改變目標和動作。目標-動作機制經常用於通知定制控制器對象將數據從用戶界面傳遞給模型對象,或者將模型對象的數據顯示出來。Cocoa綁定技術則可以避免這種用法,有關這種技術的更多信息請參見Cocoa綁定編程主題文檔。Application Kit中的控件和單元並不保持它們的目標。相反,它們維護壹個對目標的弱引用。進壹步的信息請參見"委托、觀察者、和目標的所有權" 部分。進壹步閱讀:更多信息請參見"目標-動作機制"部分。 合成模式這種模式將互相關聯的對象合成為樹結構,以表現部分-全部的層次結構。它使客戶代碼可以統壹地處理單獨的對象和多個對象的合成結果。合成對象是模型-視圖-控制器聚集模式的壹部分。視圖層次結構壹個窗口包含的視圖對象(NSView對象)在內部構成了壹個視圖層次結構。層次結構的根是窗口對象(NSWindow對象)和它的內容視圖。內容視圖就是填充到窗口內容方框中的透明視圖,添加到內容視圖中的視圖都是它的子視圖,而這些子視圖又會成為下壹級視圖的父視圖。壹個視圖有壹個(且只有壹個)父視圖,可以有零或多個子視圖。在視覺上,您可以將這個結構理解為包含關系:父視圖包含它的子視圖。圖4-2顯示視圖層次的結構以及在視覺上的關系。 圖4-2 視圖層次的結構及其在視覺上的關系 視圖層次是壹個結構方面的架構,在圖形描畫和事件處理上都扮演壹定的角色。壹個視圖有兩個影響圖形操作位置的邊界框,即邊框(frame)和邊界(bound)。邊框是外部邊界,表示視圖在其父視圖坐標系統中的位置,它負責定義視圖的尺寸,並根據視圖邊界對圖形進行裁減。邊界則是內部的邊界框,負責定義視圖對象自身描畫表面的內部坐標系統。當窗口系統要求壹個窗口做好顯示準備時,父視圖會在其子視圖之前被要求進行渲染。當您向壹個視圖發送消息時—比如發送壹個重畫視圖的消息—該消息就會被傳播到子視圖。因此,您可以將視圖層次結構中的壹個分支當成壹個統壹的視圖來處理。響應者鏈也把視圖層次用於處理事件和動作消息。請參見責任鏈模式部分中("責任鏈模式")關於響應者鏈的總結描述。使用和限制無論以編程的方式,還是通過Interface Builder,當您將壹個視圖加入到另壹個視圖中時,都需要創建或修改視圖層次結構。Application Kit框架自動處理與視圖層次結構相關聯的所有關系。進壹步閱讀:如果需要了解更多視圖層次結構的信息,請閱讀本文檔的"視圖層次結構"部分。Cocoa描畫指南文檔中也對視圖層次結構進行討論。 裝飾模式這種模式動態地將額外的責任附加到壹個對象上。在進行功能擴展時,裝飾是子類化之外的壹種靈活的備選方法。和子類化壹樣,采納裝飾模式可以加入新的行為,而又不必修改已有的代碼。裝飾將需要擴展的類的對象進行包裝,實現與該對象相同的接口,並在將任務傳遞給被包裝對象之前或之後加入自己的行為。裝飾模式表達了這樣的設計原則:類應該接納擴展,但避免修改。壹般性的說明裝飾是用於對象合成的模式。在您自己的代碼中應該鼓勵使用對象的合成(參見"什麽時候需要生成子類"部分)。然而,Cocoa自己提供了壹些基於這種模式的類和機制(在下面的部分進行討論)。在這些實現中,擴展對象並不完全復制它所包裝的對象的接口,雖然具體實現中可以使用不同的技術來進行接口***享。Cocoa在實現某些類時用到了裝飾模式,包括NSAttributedString、NSScrollView、和NSTableView。後面兩個類是復合視圖的例子,它們將其它壹些視圖類的對象組合在壹起,然後協調它們之間的交互。委托委托是在宿主對象中嵌入壹個指向另壹對象(也就是委托對象)的弱引用(壹個未保持的插座變量),並不時地向該委托對象發送消息,使其對有關的任務進行輸入的機制。宿主對象壹般是壹個“復活”的框架對象(比如壹個NSWindow或NSXMLParser對象),它尋求完成某項工作,但又只能以壹般的方式來進行。委托幾乎總是壹個定制類的實例,它負責配合宿主對象,在有關任務的特定點(參見圖4-3)上提供與具體程序有關的行為。這樣,委托機制使我們可以對另壹個對象的行為進行修改或者擴展,而不需要生成子類。 圖4-3 框架對象向它的委托對象發送消息 簡而言之,委托就是壹個對象將任務委托給另壹個對象,它是面向對象編程的常用技術。然而,Cocoa以獨特的方式實現委托機制。宿主類用非正式協議—即NSObject中的範疇—來定義委托對象可能選擇實現的接口。委托對象不必象采納正式協議那樣實現所有的協議方法。在向委托對象發送消息之前,宿主對象可以首先確定相應的方法是否實現(通過respondsToSelector:消息),以避免運行時例外。有關正式協議和非正式協議的更多信息,請參見"協議"部分。Cocoa框架中的壹些類也向它們的數據源發送消息。數據源在各個方面都和委托壹樣,除了它的目的是為宿主對象提供數據,以傳遞給瀏覽器、表視圖、或者類似的用戶界面視圖。和委托不同的是,數據源還必須實現某些協議方法。委托不是裝飾模式的嚴格實現。宿主(委托)對象並沒有包裝它希望擴展的類的實例。相反,委托是對委托框架類的行為進行特殊化。除了框架類聲明的委托方法之外,它們也沒有公***的接口。Cocoa中的委托也是模板方法模式("模板方法模式")的壹部分。使用和限制委托是Cocoa框架中的壹種常用的設計。Application Kit框架中的很多類都向它們的委托發送消息,包括NSApplication、NSWindow、和NSView的幾個子類。Foundation框架中的壹些類,比如NSXMLParser和NSStream,也維護自己的委托。您應該總是使用類的委托機制,而不是生成類的子類,除非委托方法不能完成您的目標。雖然您可以動態地改變委托,但是同時只能有壹個對象可以成為委托。因此,如果您希望當特定的程序事件發生時,有多個對象可以同時得到通知,則不能使用委托。在這種情況下您可以使用通告機制。如果委托對象實現了壹或多個框架類聲明的通告方法,就會自動接收到其委托框架對象的通告。請參考觀察者模式( "觀察者模式")中有關通告的討論。Application Kit框架中的向外委托任務的對象並不保持它們的委托或數據源,而是維護壹個弱引用,更多信息請參見"委托、觀察者、和目標的所有權"部分。進壹步閱讀:關於委托的進壹步信息請參見"委托和數據源"部分。 範疇範疇是Objective-C語言的壹個特性,用於為壹個類增加方法(接口和實現),而不必生成子類。類原始聲明的方法和通過範疇添加的方法在運行時沒有區別—在您的程序的作用範圍內。範疇中的方法成為類類型的壹部分,並被所有的子類繼承。和委托壹樣,範疇並沒有嚴格適配裝飾模式。它實現了該模式的目的,但采用不同的實現方式。範疇加入的行為是在編譯時生成的,而不是動態得到的。而且,範疇並沒有封裝被擴展的類的實例。使用和限制Cocoa框架中定義了很多範疇,大多數都是非正式協議(在"協議"部分中進行總結)。它們通常使用範疇來對相關的方法進行分組。您也可以在代碼中實現範疇,以在不生成子類的情況下對類進行擴展,或者對相關的方法進行分組。但是您需要註意如下兩點:您不能為類添加實例變量。如果您對現有的方法進行重載,則應用程序可能產生預料之外的行為。進壹步閱讀: 更多有關範疇的信息請參見Objective-C編程語言壹文中的“類的擴展”部分。 表觀模式這種模式為子系統中的壹組接口提供統壹的接口。表觀模式定義壹個更高級別的接口,通過減少復雜度和隱藏子系統之間的通訊和依賴性,使子系統更加易於使用。NSImageNSImage類為裝載和使用基於位圖(比如JPEG、PNG、或者TIFF格式)或向量(EPS或PDF格式)的圖像提供統壹的接口。NSImage可以為同壹個圖像保持多個表示,不同的表示對應於不同類型的NSImageRep對象。NSImage可以自動選擇適合於特定數據類型和顯示設備的表示。同時,它隱藏了圖像操作和選擇的細節,使客戶代碼可以交替使用很多不同的表示。使用和限制由於NSImage支持幾種不同的圖像表示,因此某些屬性可能不能適用。舉例來說,您可能不能取得圖像中壹個像素的顏色,如果潛在的圖像表示使基於向量且與設備無關的話。請註意:NSImage和圖像表示的討論請參見Cocoa描畫指南。 叠代器模式這種模式提供壹種順序訪問聚合對象(也就是壹個集合)中的元素,而又不必暴露潛在表示的方法。叠代器模式將訪問和遍歷集合元素的責任從集合對象轉移到叠代器對象。叠代器定義壹個訪問集合元素的接口,並對當前元素進行跟蹤。不同的叠代器可以執行不同的遍歷策略。NSEnumeratorFoundation框架中的NSEnumerator類實現了叠代器模式。NSEnumerator抽象類的私有具體子類返回的枚舉器對象可以順序遍歷不同類型的集合—數組、集合、字典(值和鍵)—並將集合中的對象返回給客戶代碼。NSDirectoryEnumerator是壹個不緊密相關的類,它的實例可以遞歸地枚舉文件系統中目錄的內容。使用和限制象NSArray、NSSet、和NSDictionary這樣的集合類都包含相應的方法,可以返回與集合的類型相適用的枚舉器。所有的枚舉器的工作方式都壹樣。您可以在循環中向枚舉器發送nextObject消息,如果該消息返回nil,而不是集合中的下壹個對象,則退出循環。仲裁者模式這種模式定義的對象用於封裝壹組對象的交互機制。仲裁者模式可以避免對象之間顯式的互相引用,使對象之間的耦合變得寬松,也使您可以獨立地改變它們的交互方式。這些對象也因此可以更具重用性。仲裁者對象集中了系統中的對象之間的復雜通訊和控制邏輯。這些對象在狀態發生改變時會告訴仲裁者對象,反過來,也對仲裁者對象的請求進行響應。控制器類模型-視圖-控制器設計模式為壹個面向對象的系統(比如壹個應用程序)中的對象分配不同的角色。它們可以是模型對象,包含應用程序的數據及對那些數據進行操作;可以是視圖對象,負責表示數據及響應用戶動作;也可以是控制器對象,負責協調模型和視圖對象。控制器對象適合於仲裁者模式。在Cocoa中,控制器對象壹般有兩個類型:仲裁控制器或者協調控制器。仲裁控制器負責仲裁應用程序中視圖對象和模型對象之間的數據流。仲裁控制器通常是NSController對象。協調控制器則負責實現應用程序的集中化通訊和控制邏輯,作為框架對象的委托和動作消息的目標。它們通常是NSWindowController對象或定制NSObject子類的實例。由於協調控制器高度專用於特定的程序,因此不考慮重用。Application Kit框架中的NSController抽象類和它的具體子類是Cocoa綁定技術的壹部分,該技術可以自動同步模型對象包含的數據和視圖對象中顯示及編輯的數據。舉例來說,如果用戶在壹個文本框中編輯壹個字符串,綁定技術會將文本框中的變化(通過仲裁控制器)傳遞給綁定了的模型對象中合適的屬性。編程者需要做的就是正確設計自己的模型對象,並通過Interface Builder在程序的視圖、控制器、和模型對象之間建立綁定關系。具體的公***控制器類的實例可以在Interface Builder的控件選盤上得到,因此是高度可重用的。它們提供壹些服務,比如選擇和占位符值的管理。這些對象執行下面這些特定的功能:NSObjectController 管理壹個單獨的模型對象。NSArrayController 管理壹個模型對象數組,以及維護壹個選擇;還可以在數組中加入或刪除模型對象。NSTreeController 使您可以在壹個具有層次的樹結構中添加、刪除、和管理模型對象。NSUserDefaultsController 為預置(用戶缺省值)系統提供壹個便利的接口。使用和限制您通常可用將NSController對象用作仲裁控制器,因為這些對象的設計目的是在應用程序的視圖對象和模型對象之間傳遞數據。在使用仲裁控制器時,您通常是從Interface Builder選盤中拖出對象,指定模型對象的屬性鍵,並通過Interface Builder Info 窗口中的Bindings面板建立視圖和模型對象之間的綁定關系。您也可以生成NSController或其子類的子類,以獲得更具具體行為的子類。幾乎任何壹對對象之間都可以建立綁定關系,只要它們遵循NSKeyValueCoding和NSKeyValueObserving這兩個非正式協議。但是,我們推薦您通過仲裁控制器來建立綁定,以得到NSController及其子類為您提供的各種好處。協調控制器通過下面的方式集中實現壹個應用程序的通訊和控制邏輯:維護指向模型和視圖對象的插座變量(插座變量是指向其它被保持為實例變量的連接或引用)。通過目標-動作機制響應用戶在視圖對象上的操作(參見"目標-動作"部分)。作為委托對象,處理從框架對象發出的消息(參見"委托"部分)。您通常可以在Interface Builder中建立上述的連接—插座變量、目標-動作、和委托,它將這些連接歸檔到應用程序的nib文件中。進壹步閱讀: 有關仲裁控制器、協調控制器、和與控制器有關的設計決定的討論,請參見"模型-視圖-控制器設計模式"部分。 備忘錄模式這種模式在不破壞封裝的情況下,捕捉和外部化對象的內部狀態,使對象在之後可以回復到該狀態。備忘錄模式使關鍵對象的重要狀態外部化,同時保持對象的內聚性。歸檔歸檔將壹個程序中的對象以及對象的屬性(包括屬性和關系)存儲到檔案上,使之可以保存到文件系統中,或者在不同的處理器和網絡間傳遞。檔案將程序的對象圖保存為獨立於架構的字節流,對象的標識和對象之間的關系都會被保留。由於對象的類型和它的數據壹起被存儲,從歸檔的字節流解碼出來的對象會被正常實例化,實例化所用的類與原來編碼的類相同。使用和限制通常情況下,您希望將程序中需要保存狀態的對象歸檔。模型對象幾乎總是屬於這個範疇。您通過編碼將對象寫入到檔案中,而通過解碼將對象從檔案中讀取出來。通過NSCoder對象可以執行編解碼操作,在編解碼過程中最好使用鍵化的歸檔技術(需要調用NSKeyedArchiver和NSKeyedUnarchiver類的方法)。被編解碼的對象必須遵循NSCoding協議;該協議的方法在歸檔過程中會被調用。進壹步閱讀: 有關歸檔的進壹步信息。 屬性列表的序列化屬性列表是壹個簡單的、具有壹定結構的對象圖序列,它僅使用下面這些類的對象:NSDictionary、NSArray、NSString、NSData、NSDate、和NSNumber。這些對象通常也被稱為屬性列表對象。Cocoa中有幾個框架類提供了序列化屬性列表對象,以及定義錄寫對象內容及其層次關系的特殊數據流格式的方法。NSPropertyListSerialization類就提供了將屬性列表對象序列化為XML或其它優化的二進制格式的類方法。使用和限制如果對象圖中包含的是簡單對象,則在捕捉和外部化對象及其狀態時,屬性列表序列化是壹種靈活的、可移植的、而又非常適當的工具。然而,這種形式的序列化有它的限制,它不保留對象的全部類標識,而只保留壹些壹般的類型(數組、字典、字符串、等等)。這樣,從屬性列表恢復出來的對象可能和原來的類不同,特別是當對象的可變性可能發生變化時,這就會帶來問題。屬性列表序列化也不跟蹤在同壹對象中被多次引用的對象,這可能導致反向序列化時產生多個實例,而在原來的對象圖中卻只有壹個實例。進壹步閱讀: 有關屬性列表序列化的更多信息。 Core DataCore Data是壹個管理對象圖,並使其留存的框架和架構。正是第二種能力—對象的留存能力—使Core Data成為備忘錄模式的壹種適配形式。在Core Data架構中,中心的對象稱為被管理對象上下文,負責管理應用程序對象圖中的模型對象。在被管理對象上下文下面是該對象圖的持久棧,也就是壹個框架對象的集合,負責協調模型對象和外部數據存儲,比如XML文件或關系數據庫。持久棧對象負責建立存儲中的數據和被管理對象上下文中的對象之間的映射關系,在有多個數據存儲的時候,持久棧對象將這些存儲表現為被管理對象上下文中的壹個聚合存儲