[iOS] Nib物件生存週期

蘋果官方手冊:

https://developer.apple.com/library/mac/#DOCUMENTATION/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW19

本翻譯僅提供學習,請勿挪作商業用途,歡迎各位先進指點。

The Object Loading Process
物件載入過程

當你使用NSNib或是NSBundle方法去載入且實例(instantiate,複製原始物件並回傳)化NIB裡面的物件時,底層程式會作以下的動作:

  1. 載入nib檔案的內容以及任何referenced resource檔案到記憶體中:

    • 整個nib檔案的物件圖(object graph)都會載入到記憶體中,但不會解封存(unarchived)。
      unarchived是一種將一群彼此有相關的物件轉換成可以儲存或是可在app之間互相傳遞的形式的過程。
    • 任何和nib檔案有關的custom image resources都會被載入並加入到Cocoa image cache。(參考About Image and Sound Resources.)
    • 任何和nib檔案有關的custom sound resources都會被載入並加入到Cocoa sound cache。(參考About Image and Sound Resources.)
  2. 解壓縮nib物件圖data,並且實例化物件。新物件初始化的方法端視物件的類別(type)和該物件如何編碼到歸檔(encoded in the archive)有關。Nib-loading程式碼以下列規則來決定該使用哪個初始化方法:

    1. 預設下,物件會接收initWithCoder:訊息。

      • 在OS X中,標準物件列表,包含view、cells、menus和view controllers都由系統提供並且可於預設的Xcode library中可取得。包含了使用custom plug-in加入到library的第三方(third-party)物件。即使你改變了物件類別,Xcode編碼(encode)標準物件到nib檔然後當物件要解壓縮時告訴歸檔器(archiver)去調換(swap,此處我的解讀是,當編碼壓縮某個我們製作的子類別物件時,xcode會依照我們該物件的標準類別((當然也是其父類別))的來壓縮之,等到解壓縮時,就會將物件類別換回我們的子類別)。
      • 在iOS中,任何遵守NSCoding協議的物件會使用initWithCoder:方法來初始化。這包含了任何UIView和UIViewController的子類別,不管這些子類別是否是預設Xcode library的一部分或是你定義的子類別
    2. OS X中的custom view會接收initWithFrame:訊息。

      • Custom view為NSView的子類別,Xcode無法取得他們的實作。最典型的,就是你在你的app中定義的view並用來提供custom可視內容。Custom view不包括那些為預設library或integrated third-party plug-in的標準系統view(像是NSSlider)
    3. 除以上描述外的其他物件都是用init來初始化。

    • 重建nib檔案內所有的連結(connections)(像是actions, outlet和binding)包括到file’s owner和其他placeholder物件的連結。建立連結的方式會隨著platform的不同而不同:

      1. Outlet連結

        • 於OS X中,nib-loading程式碼會先試著使用物件的方法去再連結(reconnect)outlet。對每一個outlet,Cocoa會尋找setOutletName:形式的方法,若這樣的方法存在,就會呼叫它。若找不到這樣的方法,Cocoa會尋找有對應的outlet名稱的實例變數(省略未翻完)

        • 若是iOS,nib-loading程式碼會使用setValue:forKey:去再連結(reconnect)每一個outlet,此方法類似於去尋找適當的accessor方法,且當此失敗時,會用不同的方式。若要更詳細了解此方法是如何設定數值,請參考NSKeyValueCoding Protocol Reference。

          在iOS內設定outlet也會對任何已登記的觀察者(observer)產生KVO通知(notification),這些通知於所有inter-object connection再建立前發生,並且一定於物件任何的awakeFromNib被呼叫前發生。關於KVO通知,請參考Key-Value Observing Programming Guide。
      2. Action連結

        • 在OS X中,nib-loading程式碼會使用源物件(source objects)的setTarget:和 setAction:方法去建立到目標物件(target object)的連結。若目標物件不回應action方法,就不會創立連結。若目標物件是nil,這action由responder chain處理。

        • 在iOS中,nib-loading程式碼會使用UIControl的addTarget:action:forControlEvents:方法去組態(configure)action。若target是nil,action會由responder chain處理。
      3. Binding

        • 於OS X,Cocoa使用source物件的bind:toObject:withKeyPath:options:方法去創造它(source物件)和它目標物件(target object)之間的連結。
    • 它會對nib檔裡面那些定義匹配的選擇子(selector)的適當物件發送awakeFromNib訊息。

      1. 在OS X中,這訊息會送到任何定義此方法的interface物件,它也會同樣送到file’s owner和任何有定義此方法的placeholder物件那。  
      2. 在iOS中,這訊息只會送到被nib-loading程式碼實例化的interface物件,它不會送到file’s owner、first responder或任何placeholder那。
    • 它會顯示那些在nib檔案裡面Visible at launch time屬性有被啟動的任何windows。


    (補充)物件圖 object graph:
    在物件導向程式中,一群物件會透過他們彼此之間的關係形成一個網路(network)〞這些關係可能是直接的參照(direct reference)或是中間的參照的鏈(chain of intermediate references)。這些物件的群(groups of objects)就稱作物件圖。物件圖可大可小,可簡單可複雜。一個包含一個單一字串物件的陣列物件就是一個小而簡的物件圖。一個物件們形成的群,包含參照到視窗、選單和它們的views以及其他支援的物件的應用程式物件就是一個大而複雜的物件圖。

    此處的圖(graph),跟數學裡面的圖論是有點關係的,若有學過圖論就知道,你把物件想象成vertex,關係想象成edge,這就會形成圖論裡面的graph了。

    有時你要去轉換一個物件圖---通常這只是應用程式中整個物件圖的一部分(section)---成可以儲存到檔案或是轉換到另一個程序(process)或設備(machine)後重建(reconstructed)的形式。這過程就叫做歸檔(archiving,或壓縮)。

    某些物件圖可能是不完整的,這些通常稱為部分物件圖(partial object graph)。包含file’s owner的placeholder的nib檔案就是一個例子。(中間省略一句沒翻)。

    留言