>>> Swift 3 中,因为 extension 中无法获取到 secondsSinceReferenceDate 属性,编译就报错了,因为它是 private 的。于是在 Swift 3 中,必须把 private 改为 fileprivate。
在 Swift 4 中,private 的属性的作用域扩大到了 extension 中,并且被限定在了 struct 和 extension 内部,这样就不需要再改成 fileprivate 了。
>>> Swift 3 中 Key Paths 的写法:
@objcMembersclassKid:NSObject{
dynamicvarnickname:String=""
dynamicvarage:Double=0.0
dynamicvarfriends: [Kid] = []
}
varben =Kid(nickname:"Benji", age:5.5)
letkidsNameKeyPath = #keyPath(Kid.nickname)
letname = ben.valueForKeyPath(kidsNameKeyPath)
ben.setValue("Ben", forKeyPath: kidsNameKeyPath)
Swift 4 中创建一个 KeyPath 用 \ 作为开头:
\Kid.nickname 可以省略基础类型部分:\.nickname
相比 Swift 3,Swift 4 的 Key Paths 具有以下优势:
类型可以定义为 class、struct
定义类型时无需加上 @objcMembers、dynamic 等关键字
性能更好
类型安全和类型推断,例如 ben.valueForKeyPath(kidsNameKeyPath) 返回的类型是 Any,ben[keyPath: \Kid.nickname] 直接返回 String 类型
可以在所有值类型上使用
>>>下标支持泛型:
有时候会写一些数据容器,Swift 支持通过下标来读写容器中的数据,但是如果容器类中的数据类型定义为泛型,以前的下标语法就只能返回 Any,在取出值后需要用 as? 来转换类型。Swift 4 定义下标也可以使用泛型了。
structGenericDictionary{
privatevardata: [Key:Value]
init(data: [Key:Value]) {
self.data = data
}
subscript(key:Key) ->T? {
returndata[key]as?T
}
}
letdictionary =GenericDictionary(data: ["Name":"Xiaoming"])
letname:String? = dictionary["Name"]// 不需要再写 as? String
>>> 字符串:
Unicode 字符串在计算 count 时的正确性改善;
varfamily =""
family +="\u{200D}"
family +="\u{200D}"
family +="\u{200D}"
print(family)
print(family.characters.count)
这个 family 是一个由多个字符组合成的字符,打印出来的结果为 。上面的代码在 Swift 3 中打印的 count 数是 4,在 Swift 4 中打印出的 count 是 1。
>>> 去掉 characters:
Swift 3 中的 String 需要通过 characters 去调用的属性方法,在 Swift 4 中可以通过 String 对象本身直接调用,例如:let values = "one,two,three..."; values.characters.startIndex;
而Swift 4 可以把上面代码中的所有的 characters 都去掉,修改如下: values.startIndex
>>> Swift 3 中写很长的字符串只能写在一行。Swift 4 可以把字符串写在一对 """ code """中
>>> Swift 4.1 新特性compactMap函数: 过滤 nil; 类型转换;筛选数据