国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Swift > 正文

swift中利用runtime交換方法的實(shí)現(xiàn)示例

2020-03-09 17:31:53
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

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的類跑一邊協(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()

第二種(類似第一種)

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)建分類調(diào)用那個(gè)一次方法

extension UIApplication{ open override var next: UIResponder?{  SwizzlingManager.enableInjection()  return super.next }}

4、在你需要的類中遵循注入?yún)f(xié)議

extension UIViewController: SwizzlingInjection{  public static func inject() {  //確保不是子類  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ì)VEVB武林網(wǎng)的支持。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到swift教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 漯河市| 夏河县| 新闻| 卢氏县| 金溪县| 延寿县| 香格里拉县| 广东省| 漳平市| 新龙县| 乐东| 通州区| 太保市| 五大连池市| 宁陕县| 黎平县| 潢川县| 高安市| 平潭县| 保德县| 潞西市| 南安市| 渝北区| 大宁县| 奉新县| 白朗县| 河西区| 彩票| 阳曲县| 会同县| 阳信县| 保山市| 伊宁县| 武陟县| 鸡泽县| 全州县| 隆尧县| 偏关县| 绵竹市| 石林| 泰和县|