鍍金池/ 教程/ iOS/ Access Control 權(quán)限控制的黑與白
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問(wèn)控制和 protected
語(yǔ)句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語(yǔ)言參考(About the Language Reference)
語(yǔ)法總結(jié)(Summary of the Grammar)
嵌套類(lèi)型
類(lèi)型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪問(wèn)控制
類(lèi)和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類(lèi)型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類(lèi)型與引用類(lèi)型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類(lèi)型不是夢(mèng)-白話 Swift 類(lèi)型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類(lèi)型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類(lèi)型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

Access Control 權(quán)限控制的黑與白

翻譯:老碼團(tuán)隊(duì)翻譯組-Arya 校對(duì):老碼團(tuán)隊(duì)翻譯組-Oberyn

如果您之前沒(méi)有接觸過(guò)權(quán)限控制,先來(lái)聽(tīng)一個(gè)小故事:

小明是五道口工業(yè)學(xué)院的一個(gè)大一新生,最近他有點(diǎn)煩惱,因?yàn)橥萁?jīng)常用他的熱水壺,好像那是自己家的一樣,可是礙于同學(xué)情面,又不好意思說(shuō)。直到有一天,他和學(xué)姐小 K 吐槽。

學(xué)姐聽(tīng)了之后,說(shuō):大學(xué)集體生活里面,大部分東西都是默認(rèn)室友可以共用的。如果你不想別人拿,我可以幫你做封印,只要打上 private 標(biāo)記,它們就看不到你的東西,更加用不了你的東西了。

小明說(shuō)哇靠學(xué)姐你還會(huì)妖法......

Swift 語(yǔ)言從 Xcode 6 beta 5版本起,加入了對(duì)權(quán)限控制(Access Control)的支持。其實(shí)權(quán)限控制和小明的物品一樣,你可以設(shè)定水壺是只有自己能用,還是只有宿舍里的人能用,還是全校都可以用。

從此以后,你可以好像神盾局局長(zhǎng)一樣,完全掌控自己的代碼塊的”保密級(jí)別“,哪些是只能在本文件引用,哪些能用在整個(gè)項(xiàng)目里,你還可以發(fā)揮大愛(ài)精神,把它開(kāi)源成只要導(dǎo)入你的框架,大家都可以使用的 API。

這三種權(quán)限分別是:

  • private 私有的

    在哪里寫(xiě)的,就在哪里用。無(wú)論是類(lèi)、變量、常量還是函數(shù),一旦被標(biāo)記為私有的,就只能在定義他們的源文件里使用,不能為別的文件所用。

  • internal 內(nèi)部的

    標(biāo)記為 internal 的代碼塊,在整個(gè)應(yīng)用(App bundle)或者框架(framework)的范圍內(nèi)都是可以訪問(wèn)的。

  • public 公開(kāi)的

    標(biāo)記為 public 的代碼塊一般用來(lái)建立 API,這是最開(kāi)放的權(quán)限,使得任何人只要導(dǎo)入這個(gè)模塊,都可以訪問(wèn)使用。

如果要把所有的愛(ài)加上一個(gè)期限,噢不,是給所有的代碼塊都標(biāo)記上權(quán)限,不累死才怪。還好 swift 里面所有代碼實(shí)體的默認(rèn)權(quán)限,都是最常用的 internal。所以當(dāng)你開(kāi)發(fā)自己的 App 時(shí),可能完全不用管權(quán)限控制的事情。

但當(dāng)你需要寫(xiě)一個(gè)公開(kāi) API 的時(shí)候,就必須對(duì)里面的代碼塊進(jìn)行“隱身對(duì)其可見(jiàn)”的 public 標(biāo)記,要么其他人是用不到的。

Private(私有級(jí)別)的權(quán)限最嚴(yán)格,它可以用來(lái)隱藏某些功能的細(xì)節(jié)實(shí)現(xiàn)方式。合理構(gòu)筑你的代碼,你就可以安全地使用 extension 和高級(jí)功能,又不把它們暴露給項(xiàng)目?jī)?nèi)的其他文件。

除了可以給整個(gè)聲明設(shè)權(quán)限,Swift 還允許大家在需要的時(shí)候,把某個(gè)屬性(property)的取值權(quán)限比賦值權(quán)限設(shè)得更加開(kāi)放。

舉個(gè)例子:
    public class ListItem {

    // ListItem 這個(gè)類(lèi),有兩個(gè)公開(kāi)的屬性
    public var text: String
    public var isComplete: Bool

    // 下面的代碼表示把變量 UUID 的賦值權(quán)限設(shè)為 private,對(duì)整個(gè) app 可讀,但值只能在本文件里寫(xiě)入
    private(set) var UUID: NSUUID

    public init(text: String, completed: Bool, UUID: NSUUID) {
        self.text = text
        self.isComplete = completed
        self.UUID = UUID
    }

    // 這段沒(méi)有特別標(biāo)記權(quán)限,因此屬于默認(rèn)的 internal 級(jí)別。在框架目標(biāo)內(nèi)可用,但對(duì)于其他目標(biāo)不可用
    func refreshIdentity() {
        self.UUID = NSUUID()
    }

    public override func isEqual(object: AnyObject?) -> Bool {
        if let item = object as? ListItem {
            return self.UUID == item.UUID
        }
        return false
        }
    }

當(dāng)我們使用 Objective-C 和 Swift 混合開(kāi)發(fā)時(shí),需要注意:

  • 如果你在寫(xiě)的是一個(gè)應(yīng)用,Xcode 會(huì)生成一個(gè)頭文件來(lái)保證兩者的可互訪性,而這個(gè)生成的頭文件會(huì)包含 public 和 internal 級(jí)別的聲明。

  • 如果你的最終產(chǎn)品是一個(gè) Swift 框架,頭文件里只會(huì)出現(xiàn)標(biāo)記為 public 級(jí)別的聲明。(因?yàn)榭蚣艿念^文件,屬于公開(kāi)的 Objective-C 接口的一部分,只有 public 部分對(duì) Objective-C 可用。)

雖然 Swift 不推薦大家傳播和使用第三方的框架,但對(duì)于建立和分享源文件形式的框架是支持的。對(duì)于需要寫(xiě)框架,方便應(yīng)用與多個(gè)項(xiàng)目的開(kāi)發(fā)者來(lái)說(shuō),要記得把 API 標(biāo)記為 public 級(jí)別。

如果您想了解更多關(guān)于權(quán)限控制的內(nèi)容,可以查看蘋(píng)果官方最新的《The Swift Language》和《Using Swift with Cocoa and Objective-C》指南, 這兩本指南在 iBooks 里面可以下載更新喔。

本文由翻譯自 Apple Swift Blog :https://developer.apple.com/swift/blog/?id=5