swift 4.2 官方文档学习笔记(十八)- Access Control

Sellen Wei
5 min readDec 24, 2018

--

Access control restricts access to parts of your code from code in other source files and modules.

You can assign specific access levels to individual types (classes, structures, and enumerations), as well as to properties, methods, initializers, and subscripts belonging to those types.

In addition to offering various levels of access control, Swift reduces the need to specify explicit access control levels by providing default access levels for typical scenarios.(有默认的访问权限)

学习完这一章,要能够回答以下几个问题:

  1. Access Levels(五个访问级别)分别是是什么,定义是什么?open , public , internal , fileprivate ,或 private
  2. 默认的访问级别是什么? Internal
  3. unit test target使用什么样的关键词?可以访问到什么access level?使用@testable 可以看到internal级别的

详解五个级别:

  • Open 访问 和 public 访问 允许实体被定义模块中的任意源文件访问,同样可以被另一模块的源文件通过导入该定义模块来访问。在指定框架的公共接口时,通常使用 open 或 public 访问。
  • Internal 访问 允许实体被定义模块中的任意源文件访问,但不能被该模块之外的任何源文件访问。通常在定义应用程序或是框架的内部结构时使用。
  • File-private 访问限制于当前文件中。当前文件的class可以互相访问fileprivate,别的文件不行
  • private 今能在自己class中访问

open 访问是最高的(限制最少)访问级别,private 是最低的(限制最多)访问级别。

open 访问仅适用于类和类成员,它与 public 访问区别如下:

  • public 访问,或任何更严格的访问级别的类,只能在其定义模块中被继承。
  • public 访问,或任何更严格访问级别的类成员,只能被其定义模块的子类重写。
  • open 类可以在其定义模块中被继承,也可在任何导入定义模块的其他模块中被继承。
  • open 类成员可以被其定义模块的子类重写,也可以被导入其定义模块的任何模块重写。

显式地标记类为 open 意味着你考虑过其他模块使用该类作为父类对代码的影响,并且相应地设计了类的代码。

Access Control Syntax

其中,internal由于是默认类型,在这里可写可不写。

Custom Types

public 的类型默认拥有 internal 级别的成员,而不是 public。如果你想让其中的一个类型成员是 public 的,你必须按实示例代码指明。这个要求确保类型的面向公众的 API 是你选择的,并且可以避免将类型的内部工作细节公开成 API 的失误。

元组类型

元组类型的访问级别是所有类型里最严格的。例如,如果你将两个不同类型的元素组成一个元组,一个元素的访问级别是 internal,另一个是 private,那么这个元组类型是 private 级别的。

Function Types

这个函数的返回类型是一个由两个在自定义类型里定义的类组成的元组。其中一个类是 “internal” 级别的,另一个是 “private”。因此,这个元组的访问级别是“private”(元组成员的最严级别)。如果不加private关键词someFuniction()是无法通过编译的

使用 public 或 internal 标注 someFunction() 的定义是无效的,使用默认的 internal 也是无效的,because public or internal users of the function might not have appropriate access to the private class used in the function’s return type.

Getters and Setters

下面的例子提供了一个定义为 public 级别的 TrackedString 结构体。结构体成员(包括 numberOfEdits 属性)因此有一个默认的 internal 级别。你可以设置 numberOfEdits 属性的getter方法为 public,setter 方法为 private 级别,通过结合 public 和 private(set) 访问级别修饰符:

尽管你可以从别的源文件中询问到 numberOfEdits 属性的当前值,但你不能从别的源文件中修改该属性的值。这个限制保护了TrackedString 编辑追踪功能的实现细节,并同时为该功能的一个方面提供方便的访问。

Initializers

必要初始化器必须和它所属类的访问级别一致。

默认初始化方法(init())与所属类的访问级别一致,除非该类型定义为 public 。如果一个类定义为 public ,那么默认初始化方法为 internal 级别。如果你想一个 public 类可以被一个无参初始化器初始化当在另一个模块中使用时,你必须显式提供一个 public 的无参初始化方法。

--

--