翻譯:老碼團(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)限分別是:
在哪里寫(xiě)的,就在哪里用。無(wú)論是類(lèi)、變量、常量還是函數(shù),一旦被標(biāo)記為私有的,就只能在定義他們的源文件里使用,不能為別的文件所用。
標(biāo)記為 internal 的代碼塊,在整個(gè)應(yīng)用(App bundle)或者框架(framework)的范圍內(nèi)都是可以訪問(wèn)的。
標(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)放。
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í)別的聲明。
雖然 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