Swift-访问控制
定义解释
在访问权限控制这块,Swift提供了5个不同的访问级别(以下是从高到低排列, 实体指被访问级别修饰的内容)
open :允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写(open只能用在类、类成员上)
public :允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写
internal :只允许在定义实体的模块中访问,不允许在其他模块中访问
fileprivate :只允许在定义实体的源文件中访问
private :只允许在定义实体的封闭声明中访问
绝大部分实体默认都是 internal 级别
访问级别的使用准则
一个实体不可以被理低访问级别的实体定义,比如:
变量\常量类型 ≥ 变量\常量
参数类型、返回值类型 ≥ 函数
父类 ≥ 子类
父协议 ≥ 子协议
原类型 ≥ typealias
原始值类型、关联值类型 ≥ 枚举类型
定义类型A时用到的其他类型 ≥ 类型A
……
元组类型
元组类型的访问级别是所有成员类型最低的那个123456internal struct Dog {}fileprivate clas ...
Swift-扩展(Extension)
定义
Swift中的扩展,有点类似于OC中的分类(Category)
扩展可以为枚举、结构体、类、协议添加新功能
可以添加方法、计算属性、下标、(便捷)初始化器、嵌套类型、协议等等
扩展不能办到的事情:
不能覆盖原有的功能
不能添加存储属性,不能向已有的属性添加属性观察器
不能添加父类
不能添加指定初始化器,不能添加反初始化器
…
计算属性1234567extension Double { var km: Double { self * 1_000.0 } var m: Double { self } var dm: Double { self / 10.0 } var cm: Double { self / 100.0 } var mm: Double { self / 1_000.0 } }
下标12345678extension Array { subscript(nullable idx: Int) - ...
Swift-高级运算符
溢出运算符(Overflow Operator)
Swift的算数运算符出现溢出时会抛出运行时错误
Swift有溢出运算符(&+,&-,&*),用来支持溢出运算123456var min = UInt8.minprint(min &- 1)//255,Int8.maxvar max = UInt8.maxprint(max &+ 1) // 0, Int8.minprint(max &* 2) // 254, 等价于 max &+ max
运算符重载(Operator Overload)
类、结构体、枚举可以为现有的运算符提供自定义的实现,这个操作叫做:运算符重载123456789101112131415161718192021222324252627282930313233343536373839404142434445struct Point { var x: Int, y: Int}// + 的重载func + (p1: Point, p2: Point) -> Point { ...
Swift-泛型
定义-泛型可以将类型参数化,提高代码复用率,减少代码量
12345678910111213141516func swapValues<T>(_ a: inout T, _ b: inout T) { (a, b) = (b, a)}var i1 = 10var i2 = 20swapValues(&i1, &i2)var d1 = 10.0var d2 = 20.0swapValues(&d1, &d2)struct Date { var year = 0, month = 0, day = 0 }var dd1 = Date(year: 2011, month: 9, day: 10)var dd2 = Date(year: 2012, month: 10, day: 11)swapValues(&dd1, &dd2)
泛型函数赋值给变量12func test<T1, T2>(_ t1: T1, _ t2: T2) {}var fn: (I ...
Swift-错误处理
错误类型
开发过程常见的错误
语法错误(编译错误)
逻辑错误
运行时错误(可能会导致闪退,一般也叫做异常)
…
自定义错误
Swift中可以通过Error协议自定义运行时的错误信息
12345enum SomeError : Error { case illegalArg(String) case outOfBounds(Int, Int) case outOfMemory}
函数内部通过throw抛出自定义Error,可能会抛出Error的函数必须加上 throws 声明
123456func divide(_ num1: Int, _ num2: Int) throws -> Int { if num2 ` 0 { throw SomeError.illegalArg("0不能作为除数") } return num1 / num2}
需要使用 try 调用可能会抛出Error的函数
1var result = try divide( ...
Swift-协议(Protocol)
定义
协议可以用来定义方法、属性、下标的声明,协议可以被枚举、结构体、类遵守(多个协议之间用逗号隔开)
1234567891011protocol Drawable { func draw() var x: Int { get set } var y: Int { get } subscript(index: Int) -> Int { get set } } protocol Test1 {}protocol Test2 {}protocol Test3 {}class TestClass : Test1, Test2, Test3 {}
协议中定义方法时不能有默认参数值
默认情况下,协议中定义的内容必须全部都实现
也有办法办到只实现部分内容,后面会体现
协议中的属性123456789101112131415161718192021222324252627282930313233proto ...
Swift-初始化,可选链
初始化器
类、结构体、枚举都可以定义初始化器
类有2种初始化器:指定初始化器(designated initializer)、便捷初始化器(convenience initializer)
12345678// 指定初始化器init(parameters) { statements}// 便捷初始化器 convenience init(parameters) {statements}
每个类至少有一个指定初始化器,指定初始化器是类的主要初始化器
默认初始化器总是类的指定初始化器
类偏向于少量指定初始化器,一个类通常只有一个指定初始化器
初始化器的相互调用规则
指定初始化器必须从它的直系父类调用指定初始化器
便捷初始化器必须从相同的类里调用另一个初始化器
便捷初始化器最终必须调用一个指定初始化器
初始化器的相互调用
这一套规则保证了,使用任意初始化器,都可以完整地初始化实例
两段式初始化
Swift在编码安全方面是煞费苦心,为了保证初始化过程的安全,设定了两段式初始化、安全检查
两段式初始化
第1阶段:初始化所有存储属 ...
Swift-继承
继承(Inheritance)
值类型(枚举、结构体)不支持继承,只有类支持继承
没有父类的类,称为:基类
Swift并没有像OC、Java那样的规定,任何类最终都要继承自某个基类
子类可以重写父类的 下标、方法、属性 ,重写必须加上 override 关键字
内存结构12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849class Animal { var age = 0 }class Dog : Animal { var weight = 0 }class ErHa : Dog { var iq = 0}let a = Animal()a.age = 10// 32print(Mems.size(ofRef: a))/*0x00000001000073e0 //类型信息0x0000000000000002 //引用计数 0x000000000000000a0x0000000 ...
Swift-闭包,闭包表达式
闭包表达式
在Swift中,可以通过func定义一个函数,也可以通过 闭包表达式 定义一个函数
12345678910111213141516171819// 函数func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }//闭包表达式var fn = { (v1: Int, v2: Int) -> Int in return v1 + v2}fn(10, 20){ (v1: Int, v2: Int) -> Int in return v1 + v2}(10, 20) //直接调用// 格式{ (参数列表) -> 返回值类型 in 函数体代码}
闭包表达式的简写12345678910111213141516171819func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) { print(fn(v1, v2))}exec(v1: 1 ...
Swift-方法,下标
方法(Method)
枚举、结构体、类都可以定义实例方法、类型方法
实例方法(Instance Method):通过实例对象调用
类型方法(Type Method):通过类型调用,用 static 或者 class 关键字定义
1234567891011class Car { static var cout = 0 init() { Car.cout += 1 } static func getCout() -> Int { cout } }let c0 = Car()let c1 = Car()let c2 = Car()print(Car.getCout()) // 3
self
在实例方法中代表实例对象
在类型方法中代表类型
在类型方法static func getCount中,cout.cout, Car.self.cout, Car.cout
mutating
结构体和枚举是值类型,默认情况下,值类型的属性不能被自身的实例方法修改
在func关键字前加 ...










