前言
在所有面向对象编程语言中有一个共同的特性:为安全考虑,任何没有必要公开的属性、变量和函数都应该定义为私有,以免被误操作修改。前面讲到在 Swift
中,同一命名空间下的所有文件都为共享,这明显不符合 OO
语言的标准。那么 Swift
中是如何定义私有属性的呢?接下来就探索一下 Swift
的私有化处理。
简介
在 Swift
中访问修饰符有5种,分别为 fileprivate
、private
、internal
、public
、open
,其中 fileprivate
和 open
是 Swift3.0
新添加的。由于过去 Swift
对于访问权限的控制,不是基于类的,而是基于文件的。这样会有问题,所以 Swift 3.0
新增了两个修饰符对原来的 private
、public
进行细分。
各修饰符的功能与区别
- internal
默认访问级别,该修饰符可写可不写,它修饰的属性或函数在同一命名空间下都可以被访问。如果修饰的是框架或者库代码,则在整个框架或库中可以被访问,框架被外部代码引用时不可以访问,同一个 app 只有一个命名空间,整个 app 内部可以访问。import UIKit internal class A { internal func show() { print("这是一个私有函数") } } internal class B : A { func test() { show() } } internal class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let b = B() b.test() } }
从上面代码中可以看出 class B 继承自 class A,那么 class A 中所有的公有属性都可以被 class B 访问到,这样做 class A 就没有任何私密可言,外界可以很轻易的修改 class A 中的东西,这样做明显是不安全的,下面就通过几个修饰符来确保类的私有化。
- private
在Swift 3
中该修饰符所修饰的属性或者函数只能在当前类里访问,Swift 4
中extension
里也可以访问被private
修饰的属性和函数。如果需要使用KVC
为属性赋值,一定不能用此修饰符。
添加了private
修饰符后的报错信息,当父类的某个属性或者函数被private
修饰后,子类是无法访问到的。
上图中的操作在Swift 3.0
中是被禁止的,在Swift 4.0
是合法的。 - fileprivate
该修饰符所修饰的属性或者方法在当前的Swift
源文件里可以访问。
上图中将private
改成fileprivate
之后,子类可以正常访问父类信息,但其他类是无法访问到 class A的Show()
- public
被该修饰符修饰的属性或者函数可以在任何地方被访问,但在module
外不可以被重写(override
) 和继承(Inheritance
)。不需要使用import
引入就可以创建该对象的称之为module
内,需要import
引入才可以创建该对象的称之为module
外。抱歉,这个修饰符我想不到办法展示。 - open
被该修饰符修饰的属性或者函数可以在任何地方被访问,也可以被重写(override
) 和继承。
总结
-
internal
默认访问级别,同一命名空间下可以被访问; -
private
绝对私有,除了自己和extension
以外任何地方都不可以被访问,KVC
无法通过路径找到被private
修饰的属性; -
fileprivate
相对私有,在同一源文件内可以被访问; -
public
相对公有,可以在任何地方被访问,但在module
外不可以被重写和继承。 -
open
绝对公有,可以在任何地方被访问和重写以及继承。