学习swift中的一些记录
swift
常用的几个协议
在编写一个协议时,定义只读属性不要使用let
,而是使用var
并设置为只有get方法
使用协议的方法时,注意要在方法里使用[weak self]
Hashable : 可哈希化
Hashable继承于Equatable协议
在标准库中,大部分基本类型都是遵循Hashable协议的,如Int、String等
使用
Dictionary
或Set
等数据结构时,要求作为Key
的类型要实现Hashable协议在swift4.2之后,如果一个struct中包含的数据类型是基本类型,那么在使它遵循Hashable时编译器会自动为它生成一组
==
和hash(into:)
函数。1
2
3
4
5//如果想自己实现hash函数,大多数情况下这样就可以
func hash(into hasher: inout Hasher) {
hasher.combine(xxx)
hasher.combine(xxx)
}
Codable : 可以转解码
- Codable 实际上是由Encodable & Decodable 组成
- 遵循Codable协议的对象会自动实现Encodable & Decodable
- Decodable协议定义了一个初始化函数:
init(from decoder: Decoder) throws
- Encodable协议定义了一个方法:
func encode(to encoder: Encoder) throws
- 使用遵循
Codinkey
协议的一个enum可以自定义要解析的键值名 - Codable的主要使用场景是将JSON数据解析为模型数据,需要将要解析的内容设置成可选型,否则如果JSON中某数据为空的话将会解析失败。
- 解析数据时只需要使用一个JSONDecoder实例,调用它的decode的方法就可以实现解析。如
let student = try JSONDecoder().decode(Student.self,from: json)
Equatable : 可比较
- 基本操作类型默认实现了Equatable
- 要让自定义类型实现
Equatable
的话,可以使用extension
,在extension
中遵循Equatable协议,并且实现需要的例如==
等方法 - Comparable协议类似
Identifiable
- 为类型确定一个唯一标识符
- 实现
Identifiable
协议的类型可以在For等循环中迭代 - 需要
var id : Int
@propertyWrapper
1.处理属性赋值时的值
- 实现一个可以裁剪掉字符串空格的属性修饰器
1 | @propertyWrapper |
2.保证某个属性的值满足一定条件
- 在swift和oc中,调用URL的字符串初始化方法,如果字符串中含有如中文的非法字符,则会初始化失败,URL会返回nil
- 这时就可以用一个
@propertyWrapper
修饰变量,使它在赋值时自动转换成合法的字符串
1 | @propertyWrapper |
泛型
泛型是swift中的一个重要特性,使用泛型可以减少重复代码的编写,同时提高代码的通用型。结合
where
关键词可以提高可靠性。
1.在设计一个交换两个实例值的方法时,如果不使用泛型,将需要重复实现各个类型的方法。
如:
1 | func swapTwoInts(_ a: inout Int, _ b: inout Int) { |
2.使用泛型后,用占位符<T>
代替具体的参数类型,达到一个方法可以传入多个类型的参数的目的。
如:
1 | func exchange<T>(_ lhs: inout T, _ rhs: inout T) where T:Comparable{ |
其中,inout
关键词使得函数可以修改传入参数的值,where
语句限定了方法参数的类型需要实现Comparable
协议,可以自行做其他的限定。<T>
仅起到占位符的作用,swift编译器不会去寻找名为T的类型,而是会自动推断出参数的类型。
关联类型
1.与泛型的作用类似,关联类型让开发者不用在第一时间指定具体的类型。但关联类型是在用协议上的。
2.在定义一个协议时,如果我们使用关联类型,形如:
1 | protocol Container { |
那么,Container
协议可以作为任何类型的容器,只需要在实现协议时指定时便可。
3.给关联类型添加约束,只需要 associatedtype ItemType : xxx