Aspect Oriented Programming (面向切面編程)
先來看WikiPedia對AOP介紹:
AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code (an advice) without modifying the code itself, instead separately specifying which code is modified via a "pointcut" specification.
這句話是說把一些與主邏輯無關(guān)的瑣碎事務(wù)分離出來奸绷,作為獨立的模塊就轧。在 Objective-C 的世界里麻敌,就可以利用 Runtime 特性給指定的方法添加自定義代碼怨酝。實現(xiàn) AOP 有多種方式 ,Method Swizzling(Swift中使用Method Swizzling) 是其中之一柄瑰,現(xiàn)在有一些第三方庫可以讓你不需要了解 Runtime 换吧,就能直接開始使用 AOP, 如Aspects甲抖。
Aspects使用Demo
對所有ViewController里面viewDidLoad漆改,都加上一些配置,可以寫一個extension:
extension UIViewController {
func SSViewDidLoad() {
self.navigationController?.navigationBar.translucent = true// iOS7使用appearance設(shè)置translucent會crash
print("SSViewDidLoad")
self.view.backgroundColor = UIColor.whiteColor()
if self.respondsToSelector("edgesForExtendedLayout") {
self.edgesForExtendedLayout = .None
}
}
}
寫一個結(jié)構(gòu)體AppConfig准谚,寫一個靜態(tài)方法SSViewControllerConfig:
static func SSViewControllerConfig() {
let wrappedBlock:@convention(block) (AspectInfo)-> Void = { aspectInfo in
let instance = aspectInfo.instance() as? UIViewController
instance?.SSViewDidLoad()
}
let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, AnyObject.self)
do {
try UIViewController.aspect_hookSelector("viewDidLoad", withOptions: .PositionAfter, usingBlock: wrappedObject)
} catch {
print(error)
}
}
然后在AppDelegate里面的AppConfig.SSViewControllerConfig()調(diào)用來看aspect_hookSelector方法挫剑,這是Aspects庫提供的,注意到usingBlock后面的參數(shù)是AnyObject, 需要用unsafeBitCase對block轉(zhuǎn)一下柱衔。
后記
Swift本身沒有Runtime樊破,是利用的 objective-C Runtime 特性愉棱。對于 Aspect Oriented Programming ,面向切面編程哲戚,能夠很好的獨立出模塊而不影響全局邏輯羽氮,對ViewController的配置是其中一個應(yīng)用,還有其它如打Log等惫恼。