阅读 78

Swift 关键词系列 ——— 访问控制

在自定义布局的封装Auto Layout那篇文章中 我们用到了 fileprivate 这个关键词,今天我们将会来介绍。

访问控制

访问控制的概念使我们能够限制其他代码如何访问类型、函数和其他声明。Swift 提供了五种不同级别的访问控制,充分利用它们对于编写具有明确分离的关注点和健壮结构的程序至关重要。首先老规矩先把官方地址摆上:访问控制

访问控制有五个不同的级别,他们不仅与源文件中定义的实体相关,同时也与源文件所属的模块相关。下面来介绍这五个不同的级别。

internal

当我们在 Swift 中定义任何新的类型、属性或函数时,它会默认具有internal访问级别。这意味着它将对位于同一模块中的所有其他代码可见- 例如app、extension、framework或 swift package。

internal class Test {
   func test()  { // internal func test
      //TODO:...
   }
}复制代码

public

上面的代码由于目前没有指定任何明确的访问级别,我们可以从app的任何地方访问Test 类里面的testInternal方法。但是如果我们希望与其他模块共享我们的新类(例如,我们可能会在我们的主应用程序和扩展程序或配套的 Apple Watch 应用程序之间共享的框架中实现它),那么我们将需要使用public在类在这些外部访问:

public class Test {
    public func test() {
       //TODO:...
    }
}复制代码

我们现在能够Test在其模块的内部和外部找到、并且初始化和调用我们的模块。但是现在假设我们还希望对其进行子类化操作,以对其进行修改或向其添加新功能。使用public虽然这在它自己的模块中是可行的,但这些操作是在它自己的模块之外被不允许的。这个时候将需要使用open这个关键词了:

open

open class Test {
   open func test() {
       //TODO:...
    }
}复制代码

更改成open,我们就可以在任何地方创建自定义Test子类——它们可以有新的初始化器、新的属性和新的方法。

open class SubTest : Test {
    func test() {
       //TODO:...

    }
}复制代码

上面提到了访问控制级别的从默认到扩大范围,那下面要说缩小范围的哟。我们想将范围控制在一个同一文件中,那我们需要使用fileprivate

fileprivate

class Test {
    fileprivate var num : Int = 0
    fileprivate func testPublic() {
       //TODO:...

    }
}复制代码

这里时候我就只能在同一个文件的类或者扩展里面去访问它:

class TestPublic {
    func testPublic() {
       //TODO:...
        let test = Test()
        test.num = 1
    }
}复制代码

这个时候我们想访问控制权限在缩小。想并将实体的使用限制为实体声明及其扩展,并且扩展必须在同一个文件中定义。这个时候就需要private这个关键词。

private

class Test {
    private var num : Int = 0
}复制代码

这样我们就默认到放大以及默认到缩小都简单的过了一边。

open和public

允许在定义模块(目标)之外使用实体,通常在指定框架的公共接口时使用openpublic访问。

  • open:此访问级别无处不在,可以在函数内、类内、文件内、目标外访问,甚至还可以覆盖

  • public:与 open 相同,但是不能覆盖。

但是,open访问仅适用于实体和实体成员,它与public访问的区别如下:

  • public 实体和实体成员只能在定义模块(目标)内被子类化和覆盖。

  • open 实体和实体成员可以在定义模块(目标)内部和外部进行子类化和覆盖。

// First.framework – A.swift
 open class A {}
 
 // First.framework – B.swift
 public class B: A {} // ok

 // Second.framework – C.swift
 import First
 internal class C: A {} // ok
 
 // Second.framework – D.swift
 import First
 internal class D: B {} // error: B cannot be subclassed复制代码

fileprivate 和 private

  • fileprivate : 如果多个类存在于同一个文件中,则此访问级别区域在文件内,也可以访问。将实体的使用限制在其定义的文件中。

  • private :在你写私有成员的访问,但是属性“私有成员”只能在本实体范围内使用包括同一个文件的扩展。

fileprivate:
// First.framework – A.swift
 internal struct A {
     fileprivate static let x: Int
 }

// First.framework – A.swift
 A.x // ok
 
 // First.framework – B.swift
 A.x // error: x is not available
 
 
 private:
 // First.framework – A.swift
 internal struct A {
     internal static func test() {
         x // ok
     }
 }
 
 // First.framework – C.swift
 internal class C {
     internal static func test() {
        A.x // error: x is unavailable
     }
 }
 复制代码

注意点

协议中不能使用open、public、internal、fileprivate、private修饰符。

总结

所以,总而言之,这些是 Swift 当前提供的五个级别的访问控制:

  • private将属性或函数保留在其封闭类型中,包括在同一文件中定义的该类型的任何扩展。当应用于顶级类型、函数或扩展时,它的作用与fileprivate.

  • fileprivate 使声明在定义它的整个文件中可见,同时对所有其他代码隐藏它。

  • internal 是默认访问级别,并使声明在定义它的整个模块中可见。

  • public 在其模块之外可以访问函数、类型、扩展或属性。

  • open 允许在其模块之外对类进行子类化,并覆盖函数或属性。

文章分类


作者:icc_tips
链接:https://juejin.cn/post/7030453444678778887



文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐