本帖最后由 3rdev 于 2016-8-19 09:32 编辑

前两天 Swift 3.0 更新了 beta 6,权限访问的几个关键字有了一些改变。这篇文章给大家简单介绍一下(真的很简单…)。

还有一些小改变,其中几个让人觉得很诡异:

  • 很多 Core xx 的库把 Swift原生的 Array 改成了 CFArray,很多时候需要用 as 去转换(Swift runtime 目前唯一一个比较显眼的功能…)。
  • 声明闭包的时候不能带显式 argument label, 例如 typealias completion = (data: Data, error: Error?) -> Void 就会报错, 必须加上_或者删掉参数标签。
  • 还有就是现在闭包作为参数传入的时候默认都是@nonescaping的,如果闭包不是在当前作用域内执行而是还要继续传递到别的函数里的话,那就必须加上@escaping 。
  • 引入了 Objective-C 的 id,在 Swift 叫做Any, 之前很多接口都从 AnyObject 改成了 Any, 而 Any 是没有 subscript 方法的, 看也就是说不能用键值对取值, 很多原本要通过键值对取值的写法都得先把类型强转成字典或者是 Anyobject? 。


Swift 3.0 beta 6权限访问修改

Swift 3.0 beta 6权限访问修改 - 敏捷大拇指 - Swift 3.0 beta 6权限访问修改





1、新增 open 关键字, public 变得没那么 public

beta 6 新增加了 open 关键字, 可以理解为之前的 public 。

在同一个包 module 内, public 跟 open 的含义是一样的。 但是在 module 外, open 声明的成员变量和函数是可以被 override 的, 而 public 只是把接口公开出去, 而不能被 override 。

open 大概有这么几个规则:

  • 一个类可以被声明为 open.
  • 一个类不能同时声明 open 和 final
  • 一个 open 的类的父类必须也是 open 的, 父类的父类也必须会被按照这条规则递归约束


这个主要是区分开 Module 外可访问和 Module 外可被修改这两个概念, 具体可以看[SE-0117]Allow distinguishing between public access and public overridability提案。

[Swift] 纯文本查看 复制代码
//--------Module Foo-------
class Foo {
    public var one: Int {
        return 1
    }
    open var two: Int {
        return 2
    }
}
class A: Foo {
    // 正常运行
    override var one: Int {
        return 2
    }
    // 正常运行
    override var two: Int {
        return 1
    }
}
//------End of Module------
//--------Module Bar-------
class B: Foo {
    // 报错
    override var one: Int {
        return 2
    }
    // 正常运行
    override var two: Int {
        return 1
    }
}
//------End of Module------


另外还有一点, 就是 Objective-C 的库导入的话默认都为 open, 之前是 public 。





2、默认权限更改为 fileprivate, 而 private 变得更加 private

不写任何修饰符的话, beta 6之前默认是 public。 为了安全, 我们很多时候都必须在变量和实现的函数前面加上 private , 而 beta 6现在的默认访问权限就类似于之前的 private, 默认为 fileprivate, 文件内可被访问, 文件外不可访问。

[Swift] 纯文本查看 复制代码
//---- 文件 Foo.swift ----
class Stack {
    fileprivate var one = 1
    func two() {...}
}
class Over {
    // 正常运行
    func a() {
        var foo = Foo()
        print(foo.one)
        foo.two()
    }
}
//--------- EOF ---------
//----- 文件 A.swift -----
class Flow {
    // 都报错, 提示 one 跟 two 都不可被访问
    func a() {
        var stack = Stack()
        print(stack.one)
        stack.two()
    }
}
//--------- EOF ---------


而 private 就变得更加 Private, 只有作用域内可以访问。

[Swift] 纯文本查看 复制代码
class Foo {
    private var one = 1
    var two = 2
}
extension Foo {
    func bar() {
        one = 2 // 报错
        two = 3 // 正常运行
    }
}





参考链接

[SE-0117]Allow distinguishing between public access and public overridability

What is the ‘open’ keyword in Swift?




作者:四娘