用swift写应用差不多一年多了,虽然时间还比较短,但是深刻感觉到了swift是iOS开发的未来,没有理由不去掌握它,OC的时代在我个人这里已经结束了。
这篇文章我只是讲一下我在开发过程中,使用面向协议编程中的第一个方面,虽然简单,还是希望可以起到抛砖引玉的作用吧。
为什么说面向协议编程我们要重视呢,原因很简单就是消灭: God object
进入正文:
假设你有这么个需求,所有页面的navigationBar上面都有一个编辑【菜单】之类的按钮,你会怎么做呢?大部分人一般都会用继承,让父类拥有这个Item按钮。然后每个需要它的人去继承这个父类就可以了。如图:
God object
在仔细想一下不是所有的类都会继承ViewController的。比如TableViewController等等。难道我们要去创建N个父类么?也许你会说有别的需求也是可以写到父类里面去的,总结归纳一下不就可以了?但是swift给我带来了面向协议这个编程思想。
这里举个item的例子,同样,我们可以举一反三。把想要的功能都做成协议,想怎么用直接拿过来,遵循协议即可。彻底将功能模块化。模块化的程序设计是每个程序员所追求的终极目标。我们不断的重构代码,不断的组合我们自己的代码库,原因就是这点,代码重用,功能重用,迁移方便。所以最好掌握swift面向协议编程。Mixins 比继承更好 为什么将封装改成协议的案例这篇文章有详细说明。
1.创建BlockMenuBarButton
继承自UIBarButtonItem
2.创建一个闭包用于添加按钮点击事件typealias ZKBarButtonItemBlock = () -> ()
3.并在类中写入一下代码【注释有解释】
var itemBlock: ZKBarButtonItemBlock?
// 给继承的类添加构造方法
convenience init(title: String, style: UIBarButtonItemStyle, block: ZKBarButtonItemBlock) {
// 这里自己遇到一个小小的坑,swift在书写的时候可以省略self,但是这里不能省略self
self.init(title: title, style: style, target: nil, action: #selector(barButtonItemDidTouch))
target = self
itemBlock = block
}
// 给继承的类添加构造方法
convenience init(image: UIImage, style: UIBarButtonItemStyle, block: ZKBarButtonItemBlock) {
// 同上
self.init(image: image, style: style, target: nil, action: #selector(barButtonItemDidTouch))
target = self
itemBlock = block
}
// 点击之后触发的方法
func barButtonItemDidTouch() {
guard let itemBlock = itemBlock else {
return
}
itemBlock()
}
// 添加协议
protocol MenuButtonManager {
// 添加item方法
func needMenuButtonManager()
}
// 协议扩展
extension MenuButtonManager where Self: UIViewController {
// 方法的默认实现
func needMenuButtonManager() {
let item = BlockMenuBarButton(title: "菜单", style: .Plain) {
print("这个是默认实现方法")
}
navigationItem.leftBarButtonItem = item
}
}
4.使用的时候:
class ViewController: UIViewController, MenuButtonManager {
override func viewDidLoad() {
super.viewDidLoad()
// 调用方法
needMenuButtonManager()
}
}
直接调用会触发默认方法,也可以复写协议方法
class MyTableViewController: UITableViewController, MenuButtonManager {
override func viewDidLoad() {
super.viewDidLoad()
needMenuButtonManager()
}
func needBurgerMenuManager() {
let item = BlockMenuBarButton(title: "添加", style: .Plain) {
print("自定义button1")
}
navigationItem.leftBarButtonItem = item
}
}
除了闭包的实现方法以外,还可以使用runtime,这里不介绍了。个人不是很喜欢,另外swift有意在弱化runtime所以还算是跟随形势走比较好一些。
欢迎加入我个人维护QQ群:379069176
PS:定期分享干货
网友评论