Swift 高级特性
Posted Lucky_William
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 高级特性相关的知识,希望对你有一定的参考价值。
Swift 高级特性
一、Swift 独占访问
Swift 内存安全检查:当两个变量访问同一块内存时,会产生独占内存访问限制。
发生读写权限冲突的情况:
- inout 参数读写冲突
- 结构体中函数修改成员属性读写冲突
- 值类型属性读写冲突
1. inout 参数读写冲突
// 1. Swift inout 参数读写冲突
var inputStr = "input"
func plusSlef1(_ param: inout String)
// 在 >= Swift4 版本会抛异常:同时访问0x103ed30a0,但是修改需要独占访问。
param += inputStr
// 调用下面的代码会崩溃
// plusSlef1(&inputStr)
// 同时访问同一个内存地址,造成读写冲突
func plusSlef2(_ param1: inout String, _ param2: inout String)
// 在 >= Swift4 版本会抛异常:重叠访问'inputStr',但修改需要独占访问;考虑复制到一个局部变量
let result = param1 + param2
print(result)
// 调用下面的代码会崩溃
// plusSlef2(&inputStr, &inputStr)
2. 结构体中函数修改成员属性读写冲突
// Swift 结构体中函数修改成员属性读写冲突
struct StructA
var field: Int
// mutating 修饰可修改成员属性,inout 开放写访问,会产生读写冲突
mutating func edit(_ param: inout StructA)
field = param.field
var structA = StructA(field: 100)
// 调用下面的代码会产生编译错误:
// 1. Inout参数不允许彼此别名
// 2. 重叠访问'structA',但修改需要独占访问;考虑复制到一个局部变量
// structA.edit(&structA)
3. 值类型属性读写冲突
// Swift 值类型属性读写冲突
class ClassA
// 定义元组,属于值类型
var tuple = (key1: 1, key2 : 2)
func test1(_ param1: inout Int, _ param2: inout Int)
print(param1, param2)
func test2()
// 如果被调用会崩溃,同时访问0x600000667cd0,但是修改需要独占访问。
test1(&tuple.key1, &tuple.key2)
func test3()
// 访问 局部 值变量 可以正常使用
var localTuple = (key1: 3, key2 : 4)
test1(&localTuple.key1, &localTuple.key2)
let cla = ClassA()
// 调用下面的代码会崩溃
// cla.test2()
cla.test3() // 正常调用,打印 3 4
二、Swift 增强字符串
// 多行字符串 界定符 转义符
// Swift 多行字符串,同 kotlin 的原始字符串,不需要手动添加换行符。可用于排版
var text1 = """
start
\\(1)
2
end
"""
print(text1)
// 转义符
var text2 = "对单引号进行转义\\'"
print(text2) // 对单引号进行转义'
// 使用界定符代替转义符
var text3 = #"对单引号进行转义'"#
print(text3) // 对单引号进行转义'
// 使用界定符时,转义符失去作用
var text4 = #"换行符1 \\n 换行符2"#
print(text4) // 换行符1 \\n 换行符2
// 使用界定符时,使用 \\# 保留转义符的作用
var text5 = #"换行符1 \\#n 换行符2"#
print(text5) // 会换行打印: 换行符1 换行符2
三、Swift 动态成员查找
@dynamicMemberLookup // Swift使用 @dynamicMemberLookup 为类增加动态查找成员的能力
@dynamicCallable // Swift使用 @dynamicCallable 为类增加动态方法调用的能力
class Data
var field1: Int = 0
var field2: String = ""
subscript(dynamicMember member: Int) -> String
return "class don't have the field: \\(member), type int"
subscript(dynamicMember member: String) -> String
return "class don't have the field: \\(member), type String"
// 传入一组参数
func dynamicallyCall(withArguments argArray: [Int])
print("invoke unknown func with args: \\(argArray)")
// 传入键值对参数
func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, Int>)
let argPairs = pairs.map key, value in
return "\\(key): \\(value)"
print(argPairs)
let data = Data()
// 当访问不存在的属性时,就会调用对应的 subscript 方法返回对应类型的值
// class don't have the field: someInt, type String. class don't have the field: someString, type String
print(data.someInt, data.someString)
// 调用不存在的方法,把实例当做方法调用
// 传入一组参数
data(1, 2, 3) // invoke unknown func with args: [1, 2, 3]
// 传入键值对参数
data(key1: 1, key2: 2) // ["key1: 1", "key2: 2"]
四、Swift 增强协议
// Swift 使用多个协议界定参数
protocol ProtocolA
var field: String get set
protocol ProtocolB
func method()
// 实现多个协议
class ClassImpl : ProtocolA, ProtocolB
var field: String = "impl field"
func method()
print("impl method")
// 使用 & 界定多个协议
func testImpl(impl: ProtocolA & ProtocolB)
print(impl.field)
impl.method()
testImpl(impl: ClassImpl())
GitHub 源码:AdvancedFeatures.playground
以上是关于Swift 高级特性的主要内容,如果未能解决你的问题,请参考以下文章
如何将这个 Objective-C 代码片段写入 Swift?
如何使用 Swift 使用此代码片段为 iOS 应用程序初始化 SDK?
传递额外的值 Passing Extra Values |在视图中生成输出URL | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼