iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
0
自我挑戰組

iOS 新手開發的大小事系列 第 11

Day 11: [Swift] 存取控制 (Access Control)

  • 分享至 

  • xImage
  •  

此篇將介紹前綴詞 open、public、private...等所代表的意義。Swift 提供存取控制 (access control) 的特性,可以為程式碼或模組設定存取的權限,決定哪些部分可以開放給外部的程式碼所使用,決定要隱藏的部分,如此一來,可以避免提供給外部使用時可以輕易修改內部程式碼所造成的混亂。

Swift 存取控制模型,基於模組 (model) 和 源檔案 (source file) 的概念上。
Module: 一個模組可代表一個 bundle ID 下的應用程式,或指一個 framework。因此在一個應用程式中,輸入了很多 framework,每一個 framework 內即一個 module。
Source Files: 就是指每一個 *.swift 檔案。

Swift 提供了五種不同的存取級別:

Open 存取: 擁有最高的存取權限,即最少的限制,可被同一個 module 的任何檔案存取,或一個不同的 module 存取。

public 存取: 可被同一個 module 的任何檔案存取,或一個不同的 model 存取。Classes 擁有 public 存取或更多限制的存取層級,只能在其定義的 module 為 subclasses。Classes 的成員擁有 public 存取或更多限制存取層級,只能在其定義的 module 的 subclasses 覆載。

Internal 存取: 可被其定義的 module 內的任何 sourcr file 所存取,但無法被外部 module 的任何檔案存取。當定義一個應用程式或 framework 的內部結構時,通常使用 internal 存取。

File-private 存取: 存取限制為其自定義的 source file。當在整份文件中使用這些詳細內容時,使用 file-private 存取來隱藏特定功能的實現細節。

Private 存取: 最低存取權限,即最多限制。宣告區塊和同一份檔案的擴展宣告才可存取。


存取控制語法 (Access Control Syntax)

利用在實體宣告的開頭放置 openpublicinternalfileprivateprivate 修飾符之一來定義實體的存取級別。

public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}

除非另有說明,否則預設存取級別為 internal,意思是 SomeInternalClass 和 someInternalConstant 可以在沒有顯式存取級別修飾符的情況下編寫,並且仍然具有 internal 存取級別:

class SomeInternalClass {}              // implicitly internal
let someInternalConstant = 0            // implicitly internal

自訂型別 (Custom Types)

如果要為自定義型別指定顯式訪問級別,請在定義類型時執行此操作。然後,只要存取級別允許,就可以使用新型別。例如,如果定義了文件專用類 (file-private class),則該類只能在定義了文件專用類的源文件中用為屬性的型別,或用作函數參數或返回型別。

型別的存取控制級別也會影響該型別的成員(屬性、方法、初始化程序和下標)的預設存取級別。如果將型別的存取級別定義為私有或文件私有,則其成員的預設存取級別也將為私有或文件私有。如果將惜別的存取級別定義為內部存取或公共存取(或使用內部訪問的默認訪問級別,而未明確指定訪問級別),則該型別成員的預設存取級別將是內部存取。

重要: 公用型別預設為具有內部成員,而不是公用成員。如果要讓型別成員公開,則必須明確地將其標記為公共成員。此要求確保可以選擇發布型別的面向公眾的 API,並避免錯誤地將型別的內部工作方式呈現為公共 API。

public class SomePublicClass {                  // explicitly public class
    public var somePublicProperty = 0            // explicitly public class member
    var someInternalProperty = 0                 // implicitly internal class member
    fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}

class SomeInternalClass {                       // implicitly internal class
    var someInternalProperty = 0                 // implicitly internal class member
    fileprivate func someFilePrivateMethod() {}  // explicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}

fileprivate class SomeFilePrivateClass {        // explicitly file-private class
    func someFilePrivateMethod() {}              // implicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}

private class SomePrivateClass {                // explicitly private class
    func somePrivateMethod() {}                  // implicitly private class member
}

上一篇
Day 10: [Swift] 結構和類 (Struct and Class)
下一篇
Day 12: [Swift] 錯誤處理 (Error Handling)
系列文
iOS 新手開發的大小事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言