存擋的方式有好幾種,主要的差別在儲存位置、權限及實際存擋的內容。我們介紹儲存 Encrypt 物件 (object) 的方式,要直接儲存物件需要經過序列化 (serialization) 的程序,這個需要回頭修改 Encrypt 類別 (class) ,使之繼承 (inherit) NSObject 類別,並實作 NSCoding 協定 (protocol)
NSObject 為 Cocoa 裡的最基礎的父類別 (superclass) , Cocoa 中所有類別都是由 NSObject 延伸來的。繼承 NSObject 後,建構子 (initializer) 需要加上關鍵字 (keyword) override 宣告,表示改寫父類別 NSObject 的建構子,然後在建構子的第一行先用 super 呼叫 NSObject 的建構子。
super 為子類別 (subclass) 中呼叫父類別方法所用的關鍵字,因為現在 Encrypt 繼承自 NSObject ,建立 Encrypt 物件實體時也需要先執行 NSObject 的建構子,不然可能會有些小問題。
NSCoding 協定需要實作一個帶有 NSCoder 參數 (parameter) 的建構子與 encodeWithCoder() 方法,前者需要用關鍵字 required 宣告。 encodeWithCoder() 是存擋時將每個屬性進行編碼,而建構子則時讀檔後將每個屬性解碼恢復,因此屬性就對應到同名稱的 key 。
回到 ViewController.swift ,先增加檔名屬性 (property) filename 為 "encryptor"
然後看到 saveMethod() 與 loadMethod() 的部分
存擋的 saveMethod() 方法 (method) 是利用 NSKeyedArchiver 的 archiveRootObject() 方法,這是個類別方法 (class method) ,所以直接由類別名稱呼叫。 archiveRootObject() 需要兩個參數,第一個參數為要儲存的物件,第二個參數 toFile 則是檔案名稱,結果回傳布林值,這裡依回傳結果顯示不同的提示訊息。
載入的 loadMethod() 方法則是利用 NSKeyedUnarchiver 的 unarchiveObjectWithFile() ,這要以檔名當參數。不過這裡先用 NSFileManager 的 defaultManager() 建立檔案物件,再利用檔案物件的 fileExistsAtPath() 方法回傳的布林值判斷檔案是否存在,檔案存在才進行載入。
為什麼這麼麻煩呢?因為存擋不一定會成功,如果沒有先存擋就載入,也沒有先檢查檔案是否存在的話,這會造成難以彌補的執行錯誤,所以檔案處理需要經過這些檢查步驟。
來試看看囉,下面先跑一個編碼結果
儲存 Encrypt 物件
用其他的 Encrypt 物件編碼
然後載入剛剛儲存的 Encrypt 物件
重新編碼會得到相同的結果
下一個單元我們繼續實作剩下的兩個方法,使之成為完成版的 EncryptorMacOS 專案 (project) 。
中英文術語對照
物件 | object |
序列化 | serialization |
類別 | class |
繼承 | inherit |
協定 | protocol |
父類別 | superclass |
建構子 | initializer |
關鍵字 | keyword |
子類別 | subclass |
參數 | parameter |
屬性 | property |
方法 | method |
類別方法 | class method |
專案 | project |
沒有留言:
張貼留言