讀古今文學網 > iOS編程基礎:Swift、Xcode和Cocoa入門指南 > 13.3 全局可見性 >

13.3 全局可見性

有些對象是全局可見的,也就是說,它們對所有對象都是可見的。對像類型本身就是個很好的例子。正如我在第4章所指出的那樣,我們可以在使用Swift結構體的同時通過靜態成員來提供全局可用的命名空間約束(見4.3.2節)。

有時,類會通過類方法來提供單例。這些單例反過來又提供了指向其他對象的屬性,這使得其他對象也變成全局可見的了。比如,任何對象都可以通過調用UIApplication.sharedApplication()看到單例的UIApplication實例。這樣,任何對象也都可以看到應用的主窗口,因為它是單例UIApplication實例的keyWindow屬性;任何對象也都可以看到應用委託,因為它是其delegate屬性。這個鏈條還會繼續:任何對象都可以看到應用的根視圖控制器,因為它是主窗口的rootViewController;正如13.2節所述,我們可以從這裡導航視圖控制器與視圖層次體系。

你也可以通過將自己的對象附加到全局可見對像上使其全局可見。比如,你可以自由創建的應用委託的公共屬性就是全局可見的,這是因為應用委託是全局可見的(因為共享應用是全局可見的)。

另一個全局可見對象是調用NSUserDefaults.standardUserDefaults()所返回的共享默認對象。該對象是個網關,用於存儲和獲取用戶默認值,它像是一個字典(一個值的集合,根據鍵來獲取)。當應用終止時,用戶默認值會自動保存;當應用再次啟動時,它們又會自動恢復。因此,這是應用在兩次啟動之間維護信息的一種方式。不過,由於是全局可見的,因此它們還是應用中通信的一種媒介。

比如,在我開發的一個應用中有一個名為HazyStripy的設置。它決定了某個可見的界面對像(遊戲中的一張紙牌)是模糊的還是條紋的。用戶可以修改這個設置,因此會有一個首選項界面讓用戶修改。當用戶打開這個首選項界面時,我會在用戶默認值中檢查HazyStripy設置,配置這個界面以在分割控件中反映出來(叫作self.hazyStripy)。


func setHazyStripy  {
    let hs = NSUserDefaults.standardUserDefaults
        .objectForKey(Default.HazyStripy) as! Int
    self.hazyStripy.selectedSegmentIndex = hs
}
  

相反,如果用戶操作了首選項界面,輕拍hazyStripy分割控件來修改其設置,那麼我會通過修改用戶默認值中實際的HazyStripy設置來作出響應:


@IBAction func hazyStripyChange(sender:AnyObject) {
    let hs = self.hazyStripy.selectedSegmentIndex
    NSUserDefaults.standardUserDefaults.setObject(
        hs, forKey: Default.HazyStripy)
}
  

這裡還有一個地方很有意思。首選項界面並非唯一一個使用用戶默認值中HazyStripy設置的地方;實際繪製模糊或條紋卡片的繪製代碼也會用到它,這樣才能知道卡片該如何繪製自身!當用戶關閉首選項界面,紙牌遊戲重新出現時,紙牌會被重新繪製,它會查詢NSUserDefaults中的HazyStripy設置。


override func drawRect(rect: CGRect) {
    let hazy : Bool = NSUserDefaults.standardUserDefaults
        .integerForKey(Default.HazyStripy) == HazyStripy.Hazy.rawValue
    CardPainter.sharedPainter.drawCard(self.card, hazy:hazy)
}
  

這樣,紙牌對象與管理首選項界面的視圖控制器對象就沒必要看到彼此了,因為它們都能看到這個共同的對象,即HazyStripy用戶默認值。NSUserDefaults本質上會成為一個全局的媒介,用於實現應用中不同部分之間信息的通信。