swift中利用runtime交換方法的實(shí)現(xiàn)示例
前言
Runtime介紹
學(xué)習(xí)一個(gè)東西至少要先知道它是個(gè)啥,你一定聽(tīng)說(shuō)過(guò)“運(yùn)行時(shí)是 Objective-C 的一個(gè)特色”,這里的“運(yùn)行時(shí)”就是指 runtime 了。
老的方式initialize現(xiàn)在已經(jīng)不適用了,需要用新的方式代替。
思路: 定義一個(gè)啟動(dòng)的協(xié)議,在app完成啟動(dòng)的方法里把需要做method swizzle的類(lèi)跑一邊協(xié)議的方法
第一種
1、Step One
protocol SelfAware: class { static func awake() } class NothingToSeeHere { static func harmlessFunction() { let typeCount = Int(objc_getClassList(nil, 0)) let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount) let autoreleasingTypes = AutoreleasingUnsafeMutablePointer<AnyClass?>(types) objc_getClassList(autoreleasingTypes, Int32(typeCount)) for index in 0 ..< typeCount { (types[index] as? SelfAware.Type)?.awake() } types.deallocate(capacity: typeCount) } }
2、step two
extension UIApplication { private static let runOnce: Void = { NothingToSeeHere.harmlessFunction() }() override open var next: UIResponder? { // Called before applicationDidFinishLaunching UIApplication.runOnce return super.next } }
3、step three
遵循協(xié)議SelfAware,實(shí)現(xiàn)awake()
第二種(類(lèi)似第一種)
1、創(chuàng)建一個(gè)swizzle注入的協(xié)議
public protocol SwizzlingInjection: class { static func inject() }
2、創(chuàng)建swizzle helper
open class SwizzlingManager { //只會(huì)調(diào)用一次的方法 private static let doOnce: Any? = { UIViewController.inject() return nil }() open static func enableInjection() { _ = SwizzlingManager.doOnce } }
3、給UIApplication 創(chuàng)建分類(lèi)調(diào)用那個(gè)一次方法
extension UIApplication{ open override var next: UIResponder?{ SwizzlingManager.enableInjection() return super.next } }
4、在你需要的類(lèi)中遵循注入?yún)f(xié)議
extension UIViewController: SwizzlingInjection{ public static func inject() { //確保不是子類(lèi) guard self === UIViewController.self else { return } DispatchQueue.once(token: "com.moglo.urmoji.UIViewController") { //do swizzle method } } }
once只執(zhí)行一次的方法
public extension DispatchQueue { private static var _onceTracker = [String]() public class func once(file: String = #file, function: String = #function, line: Int = #line, block:()->Void) { let token = file + ":" + function + ":" + String(line) once(token: token, block: block) } /** Executes a block of code, associated with a unique token, only once. The code is thread safe and will only execute the code once even in the presence of multithreaded calls. - parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID - parameter block: Block to execute once */ public class func once(token: String, block:()->Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if _onceTracker.contains(token) { return } _onceTracker.append(token) block() } //delay typealias Task = (_ cancel : Bool) -> Void @discardableResult static func delay(time : TimeInterval, task: @escaping () -> ()) -> Task? { func dispatch_later(block : @escaping () -> ()) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time , execute: block) } var closure : (() -> ())? = task var result : Task? let delayedClosure : Task = { cancel in if let internalClosure = closure { if cancel == false { DispatchQueue.main.async(execute: internalClosure) } } closure = nil result = nil } result = delayedClosure dispatch_later { () -> () in if let delayedClosure = result { delayedClosure(false) } } return result } static func cancel(task : Task?) { task?(true) } }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- 簡(jiǎn)單好用的iOS導(dǎo)航欄封裝.runtime屬性控制實(shí)例代碼
- OC runtime學(xué)習(xí)筆記之關(guān)聯(lián)對(duì)象
- iOS開(kāi)發(fā)中runtime常用的幾種方法示例總結(jié)
- iOS中Runtime的幾種基本用法記錄
- runtime獲取屬性和成員變量方法
- iOS利用Runtime實(shí)現(xiàn)友盟頁(yè)面數(shù)據(jù)統(tǒng)計(jì)的功能示例
- iOS runtime動(dòng)態(tài)添加方法示例詳解
- 詳解Java中Checked Exception與Runtime Exception 的區(qū)別
- Java編程使用Runtime和Process類(lèi)運(yùn)行外部程序的方法
- 將cantk runtime嵌入到現(xiàn)有的APP中的方法
相關(guān)文章
Swift類(lèi)型創(chuàng)建之自定義一個(gè)類(lèi)型詳解
這篇文章主要介紹了Swift類(lèi)型創(chuàng)建之自定義一個(gè)類(lèi)型詳解,本文講解了自定義原型、實(shí)現(xiàn)默認(rèn)值、支持基本布爾型初始化、支持Bool類(lèi)型判斷、支持兼容各們各派的類(lèi)型、完善OCBool的布爾基因體系等內(nèi)容,需要的朋友可以參考下2015-05-05Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能
這篇文章主要介紹了Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02Swift自定義iOS中的TabBarController并為其添加動(dòng)畫(huà)
這篇文章主要介紹了Swift自定義iOS中的TabBarController并為其添加動(dòng)畫(huà)的方法,即自定義TabBarController中的的TabBar并為自定義的TabBar增加動(dòng)畫(huà)效果,需要的朋友可以參考下2016-04-04