Access Control 教學(swift 4, iOS)

Jerry Wang
5 min readMar 3, 2017

--

相信大家一定常看到在class、protocol、func、var、let……等,所有的宣告前面看過前綴詞open、public、private…..等,究竟這代表什麼意義?

在swift中會有Access Control的概念形成,其實很好理解。想像一下,今天apple寫好了一個class,內部含有許多函數和屬性供你使用,但一定不希望使用者隨意修改程式碼造成系統大亂,因此只暴露出一些接口,即所謂的API (Application Programming Interface、應用程式介面),供外部使用這個class所提供的功能。

而決定要屏蔽哪些部分,開放哪些部分供使用者,即Access Control的概念。

在Access Control的世界中,最重要的兩個分野為module和source file

Module : 一個module可代表一個bundle ID下的app,一個framework因此在一個app中,import了很多framework,每一個framework內即一個module,framework外的世界,也就是你自己撰寫的這個app,也是一個module。

Source Files :就是每一個.swift檔案。舉例來說,下面圖內就有4個source file。

你撰寫的Access Control即影響了module和module間,module和source file間,source file和source file間的所有溝通情況。

在swift中Access Control可分為5個層級。由層級最高到層級最低依次為open / public / internal / file-private / private 。層級最高表示限制最少,層級最低表示限制最多。

在上面的連結中,清楚地介紹了每個層級的差異,如上圖所示。

open :用於宣告class以及class內所有的成員,層級最高,所有module和source file都可取得,且可subclass和override此class。

public:不限於class,所有module和source file都可取得,但若為class,則不可subclass和override。

internal:宣告的module內所有source file才可取得,module外無法取得。module內所有source file,若為class,可subclass和override。同時,此為預設的access control,也就代表預設的層級只能用於你寫的module內,在module外無法取得。

fileprivate:宣告的source file內才可取得,若為class,可subclass和override。

private :宣告的區塊內才可取得,也就是{ } 內才可取得。若為class,可subclass和override。

fileprivate和private的差異,舉個最明顯的例子。

在viewController.swift的檔案中,宣告為fileprivate的屬性fileprivateProperty和private的屬性privateProperty。

在viewDidLoad中,也就是宣告的{ }範圍內,fileprivateProperty和privateProperty皆可進行修改。

同樣在同一個 viewController.swift的檔案中撰寫 VIewController的extention,內部也能取得 fileprivateProperty及 privateProperty。

(更新)在swift4開始,已可在同一類別的 extention中取得宣告為 private的成員。

以上為5種層級的介紹,在宣告各種class / struct / protocol…..的過程中,只要把握一個原則,內部成員的層級不能高於最外圍的成員。

舉例來說,宣告了一個 fileprivate的class,內部的成員可以為fileprivate或private,但絕不能為open。

fileprivate class SomeClass{fileprivate var name : String = “John”privete var age : Int = 18open var height : Int = 180 //這行程式碼絕對不能通過}

詳細的內容可參考官方文件,內有更詳細的討論。

--

--