Swift泛型学习
泛型的使用
参考文章和资料
https://juejin.cn/post/6844904201839984648 理论介绍
https://github.com/JoanKing/JKSwiftExtension Swift常用扩展、组件(链式调用)、协议,方便项目快速搭建
巧妙用法
泛型的约束
1
2
// `T`约束为继承自`SomeClass`的类型 `U`约束为遵守`SomeProtocol` 协议的类型
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {}
泛型的where闭包
1
2
3
4
5
6
// where用法,是个条件判断,之前理解 `:`是表示需要实现UIButton的协议的Base才行,实际上还表示继承自UIButton的才行
public extension JKPOP where Base: UIButton {}
// 可以要求Base未UIButton的特定类型
public extension JKPOP where Base == UIButton {}
类型关联
关联类型使用关键字associatedtype
指定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 定义实现Base泛型的JKPOP的结构体
public struct JKPOP<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
public protocol JKPOPCompatible {}
// 添加JKPOPCompatible,以便后面扩展实现链式函数
public extension JKPOPCompatible {
static var jk: JKPOP<Self>.Type {
get{ JKPOP<Self>.self }
set {}
}
var jk: JKPOP<Self> {
get { JKPOP(self) }
set {}
}
}
/// Define Property protocol
internal protocol JKSwiftPropertyCompatible {
/// Extended type
associatedtype T
///Alias for callback function
typealias SwiftCallBack = ((T?) -> ())
///Define the calculated properties of the closure type
var swiftCallBack: SwiftCallBack? { get set }
}
对Button
的扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// UIView和它的子类都添加JKPOPCompatible,这样可以通过.jk的形式调用JKPOP,将自己赋值给JKPOP中的base属性
extension UIView: JKPOPCompatible {}
private var buttonCallBackKey: Void?
extension UIButton: JKSwiftPropertyCompatible {
internal typealias T = UIButton
internal var swiftCallBack: SwiftCallBack? {
get { return jk_getAssociatedObject(self, &buttonCallBackKey) }
set { jk_setRetainedAssociatedObject(self, &buttonCallBackKey, newValue) }
}
@objc internal func swiftButtonAction(_ button: UIButton) {
self.swiftCallBack?(button)
}
}
// 对UIButton的能力进行JKPOP扩展
// 扩展JKPOP约束Base泛型必须是UIButton的类型
// 这样,对属性base的操作动作都是对button的操作
public extension JKPOP where Base: UIButton {
// MARK: 5.1、button的事件
/// button的事件
/// - Parameters:
/// - controlEvents: 事件类型,默认是 valueChanged
/// - buttonCallBack: 事件
/// - Returns: 闭包事件
func setHandleClick(controlEvents: UIControl.Event = .touchUpInside, buttonCallBack: ((_ button: UIButton?) -> ())?){
base.swiftCallBack = buttonCallBack
base.addTarget(base, action: #selector(base.swiftButtonAction), for: controlEvents)
}
}
本文由作者按照 CC BY 4.0 进行授权