Swift extension 扩展实用Tips
程序员文章站
2024-03-18 12:26:22
...
extension基本功能
Swift扩展是为结构体、类和枚举增加新功能。与OC的分类相似,但是没有扩展名字。
常用于:
- 添加类/实例计算属性
- 添加类/实例方法
- 提供新便携初始化器
- 定义和使用新内嵌类型
- 使现有类型遵循某些协议
- 定义下标
更多的使用extension 可以使您的文件层次化,文件结构更清晰,更加具有面向协议编程效果,后期优化的时候能更方便。
为协议提供默认实现
Swift 定义协议默认都是必须实现,那如果想让某些方法或者属性可选实现怎么办了, 1.使用协议扩展来默认实现,2.使用optional关键字,作为Swift Style 建议选择扩展协议来达到可选功能,而且不需要使用可选链哟。
示例
// 遵守
extension ViewController: SomeOptionProtocol {
func methodB() {
}
func methodC() {
}
}
protocol SomeOptionProtocol {
func methodA();
func methodB();
func methodC(); //可选方法
}
extension SomeOptionProtocol {
func methodC() {
print("提供默认实现")
}
}
使用optional实现协议可选(不建议)
extension ViewController: SomeOptionProtocol {
func methodA() {
}
func methodB() {
}
}
@objc protocol SomeOptionProtocol {
func methodA();
func methodB();
@objc optional func methodC(); // 可选方法
}
给协议添加限制
示例
extension Collection where Iterator.Element: TextRepresentable {
var textualDescription: String {
let itemsAsText = self.map { $0.textualDescription }
return "[" + itemsAsText.joined(separator: ", ") + "]"
}
}
区分内部结构层次
当一个Swift文件(比如ViewController)遵守多个不同协议的时候,如果使用扩展遵守协议,能很好的区分文件结构。
如下图
系统类型扩展
通过扩展系统类型达到增加功能和管理作用。
Notification.Name统一管理
传统监听通知或者发送通知,通知名字常常通过字符串初始化,容易引起输入错误,和(监听和发送)增删不同步的问题。可以借助扩展进行通知定义和管理。方便调用。
通知名扩展定义
extension Notification.Name {
static let valueChanged = Notification.Name(rawValue: "valueChanged") // 值改变通知
static let newValue = Notification.Name(rawValue: "newValue") // 新值通知
}
添加通知监听
private func addNoti() {
NotificationCenter.default.addObserver(self, selector: #selector(valueChanged(noti:)), name: .valueChanged, object: nil) // 直接使用点语法
// 原始用法, 1.可能存在字符串拼错问题 2.如果注册或者监听通知之一移除,另一个可能不会及时移除。
//NotificationCenter.default.addObserver(self, selector: #selector(valueChanged(noti:)), name: NSNotification.Name("valueChanged"), object: nil)
}
更优雅的使用Selector
定义Action方法
// MARK: - Action
extension ViewController {
@objc fileprivate func button1Tapped(sender: UIButton) {
print("点击按钮1")
}
@objc fileprivate func button2Tapped(sender: UIButton) {
print("点击按钮1")
}
@objc fileprivate func button3Tapped(sender: UIButton) {
print("点击按钮1")
}
@objc fileprivate func button4Tapped(sender: UIButton) {
print("点击按钮1")
}
}
扩展Selector
// MARK: - Selector
fileprivate extension Selector { // 为了只在文件内访问,添加fileprivate
static let button1Tapped = #selector(ViewController.button1Tapped(sender:)) // 通过静态变量添加
static let button2Tapped = #selector(ViewController.button1Tapped(sender:))
static let button3Tapped = #selector(ViewController.button1Tapped(sender:))
static let button4Tapped = #selector(ViewController.button1Tapped(sender:))
}
直接通过.语法调用
/// 设置按钮
private func setupButtons() {
let button1 = UIButton(type: .custom)
button1.addTarget(self, action: .button1Tapped, for: .touchUpInside) // 点语法调用
//button1.addTarget(self, action: #selector(button1Tapped(sender:)), for: .touchUpInside) // 原始语法
//依次为buttons添加target
}
警告:该Selector扩展适合文件内有多个Selector方法时使用,毕竟需要增加多余定义代码, 建议添加权限控制,
上一篇: Python实现栈、队列和双端队列
下一篇: 「4 行代码」实现黑客帝国特效