整理下 Swift 的 Access Control

整理下 Swift 的 Access Control,第1张

概述整理下 Swift 的 Access Control~属性访问级别。 众所周知,Swift 并没有像 Objective-C 那样,有着泾渭分明的 .h 和 .m 文件可以来决定哪些参数、方法需要暴露,哪些不需要暴露。Swift 提供了五种访问级别(assess level),分别是 open、public、internal、fileprivate、private。 level open open

整理下 Swift 的 Access Control~属性访问级别。

众所周知,Swift 并没有像 Objective-C 那样,有着泾渭分明的 .h 和 .m 文件可以来决定哪些参数、方法需要暴露,哪些不需要暴露。Swift 提供了五种访问级别(assess level),分别是 open、public、internal、fileprivate、private。

level
open open 的级别,也是最高的
public public 的级别次之
internal internal 是默认的访问控制级别
fileprivate 使用 fileprivate 定义的方法和属性,只在该文件中均可以使用,包括该文件中的extension
private 使用 private 定义的方法和属性,只包括该文件中该类或结构体等的extension。

<!-- Mark -->

open & public

open 和 public 声明的属性和方法,都比较广,并且用于进行开发模块框架中。如果只是在单独的 target 中使用的话,那么没有必要用到 open 和 public,用默认的级别即可,也就是 internal。

场景
文件内 均可以进行访问等 *** 作。
模块内 可以在模块内进行访问等 *** 作。
模块外 当文件 import 模块后,可以在文件中对模块内进行访问等 *** 作。

二者的不同之处主要在:

open 声明的类,可以在模块外,也就是import 后,对模块内相应声明的类进行继承,并重载方法,而 public 声明的类,则只是在模块外对其进行继承,但不允许重载。

internal

internal 是 Swift 中的默认访问级别。一般也不用特意去声明 internal。只能用于模块内。

fileprivate & private

fileprivate 和 private 声明的属性和方法,均是私有的。但是前者更多是对文件内私有,后者则是对类型内私有。

fileprivate,顾名思义,只在文件内访问。因此,任何标明了 fileprivate 的属性和方法,均可以在该文件内进行访问使用。

private,则更多是类、结构体等内部使用。早在 Swift 3 的时候,当在同一个文件里,用 extension 对类或结构体等进行扩展时,在 extension 里是无法访问到 private 标记的属性和方法,需要使用 fileprivate。但是后面 Swift 4 又对 private 进行改变,在同一文件内,extension 里可以访问到 private 标记的属性和方法里。

所以,fileprivate 的访问级别是比 private 高的。fileprivate 是只要在同一个文件里都是可以访问的,但是 private 则多了限制。

struct Dog {    fileprivate func run() { }    private func eat() { }}extension Dog {    func eatAgain() {        eat()    }}struct Human {    fileprivate var month : String?    private var eye : String?    var dog = Dog()        func walkTheDog() {        dog.run()    }}

比如上述例子,在同一文件内,Human 可以通过 dog 来调用到 fileprivate 声明的 run(),但是无法调用到 private 声明的 eat()。而在 extension Dog 里,则可以调用到 private 声明的 eat()

另外,fileprivate 还有一些其他的用法。比如子类在和父类同一文件内可以重写 fileprivate 声明的属性和方法等。其中,如果是存储性属性的话,那么是无法进行重载的。

class Animal {    fileprivate var mouth : String { return "mouth"}    fileprivate var nose : String = ""    private var eye : String?        fileprivate func jump() { }    private func eat() { }}class Cat : Animal {    overrIDe var mouth: String { return "CatMouth" }        overrIDe func jump() { }}
get/set

另外,我们可以通过 fileprivate(set)private(set)internal(set) 来决定 set 方法的级别。

struct TrackedString {    private(set) var numberOfEdits = 0    var value: String = "" {        dIDSet {            numberOfEdits += 1        }    }}var tracked = TrackedString()tracked.numberOfEdits = 0         ❌

比如官方文档的这个?。当使用 private(set) 标明 numberOfEdits 后,当你
通过构造一个 TrackedString,想要从外部更改 numberOfEdits ,那么就会报错。这里简单的说明就是,numberOfEdits 的 get 外部可以见,而 set 由于表明了 private(set) ,那么外部不可以见,无法在外部更改。

访问权限大概就是这些。主要是在看源码的时候,发现了 private(set) 这种用法,然后去官方文档查才发现自己漏了这个知识点。于是借此机会整理了。

参考

官方文档

Allow distinguishing between public access and public overridability

总结

以上是内存溢出为你收集整理的整理下 Swift 的 Access Control全部内容,希望文章能够帮你解决整理下 Swift 的 Access Control所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1056026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存