Method Swizzling

来源:https://www.cnblogs.com/lurenq/archive/2019/09/25/11586547.html
-Advertisement-
Play Games

// Method Swizzling 的最佳實踐 // 下麵我們就以替換 viewWillAppear 方法為例談談 Method Swizzling 的最佳實踐,話不多說,直接上代碼: 下麵我們就一起來分析下這三個為什麼到底是為了什麼? 第 1 個為什麼:看過我前面文章《Objective-C ...



// Method Swizzling 的最佳實踐


// 下麵我們就以替換 viewWillAppear 方法為例談談 Method Swizzling 的最佳實踐,話不多說,直接上代碼:


@interface UIViewController (MRCUMAnalytics) @end @implementation UIViewController (MRCUMAnalytics)
+ (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(viewWillAppear:); SEL swizzledSelector = @selector(mrc_viewWillAppear:); Method originalMethod = class_getInstanceMethod(class, originalSelector); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (success) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } #pragma mark - Method Swizzling - (void)mrc_viewWillAppear:(BOOL)animated { [self mrc_viewWillAppear:animated]; [MobClick beginLogPageView:NSStringFromClass([self class])]; } @end

 

  1. 為什麼是在 +load 方法中實現 Method Swizzling 的邏輯,而不是其他的什麼方法,比如 +initialize 等;
  2. 為什麼 Method Swizzling 的邏輯需要用 dispatch_once 來進行調度;
  3. 為什麼需要調用 class_addMethod 方法,並且以它的結果為依據分別處理兩種不同的情況。

下麵我們就一起來分析下這三個為什麼到底是為了什麼?

第 1 個為什麼:看過我前面文章《Objective-C +load vs +initialize》 的同學應該知道,+load 和 +initialize 是 Objective-C runtime 會自動調用的兩個類方法。但是它們被調用的時機卻是有差別的,+load 方法是在類被載入的時候調用的,而 +initialize 方法是在類或它的子類收到第一條消息之前被調用的,這裡所指的消息包括實例方法和類方法的調用。也就是說 +initialize 方法是以懶載入的方式被調用的,如果程式一直沒有給某個類或它的子類發送消息,那麼這個類的 +initialize 方法是永遠不會被調用的。此外 +load 方法還有一個非常重要的特性,那就是子類、父類和分類中的 +load 方法的實現是被區別對待的。換句話說在 Objective-C runtime 自動調用 +load 方法時,分類中的 +load 方法並不會對主類中的 +load 方法造成覆蓋。綜上所述,+load 方法是實現 Method Swizzling 邏輯的最佳“場所”。

第 2 個為什麼:我們上面提到,+load 方法在類載入的時候會被 runtime 自動調用一次,但是它並沒有限製程序員對 +load 方法的手動調用。什麼?你說不會有程式員這麼乾?那可說不定,我還見過手動調用 viewDidLoad 方法的程式員,就是介麽任性。而我們所能夠做的就是儘可能地保證程式能夠在各種情況下正常運行。

第 3 個為什麼:我們使用 Method Swizzling 的目的通常都是為了給程式增加功能,而不是完全地替換某個功能,所以我們一般都需要在自定義的實現中調用原始的實現。所以這裡就會有兩種情況需要我們分別進行處理:

 

推薦參考鏈接: https://mp.weixin.qq.com/s/n-G9cbjiRwxNzzCO9kOf5w

值得細看一下.非常不錯

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當備份的失敗,出現說什麼應該支持多少個介質簇,但實際出現了多少介質簇,這個時候就要考慮備份的地址是不是出現問題。 首先,檢查備份地址,是不是多於兩個以上,那麼在備份的時候應該註意,備份地址最好留一個,就不會出現這個問題。 具體應該怎麼備份呢? 選擇要備份的資料庫,然後清空你不想要的備份地址,選擇你想 ...
  • 如果YourSQLDba設置過共用路徑備份(具體參考博客YourSQLDba設置共用路徑備份),有時候伺服器重啟後,備份就會出錯,具體錯誤信息類似如下所示: Date 2019/9/25 10:10:00Log SQL Server (Current - 2019/9/25 3:06:00) Sou... ...
  • 腳本需求: 每天備份mysql資料庫,保留7天的腳本。 存放在/opt/dbbak目錄中。 腳本名稱為database_xxxx-xx-xx.sql 腳本內容: #!/bin/bash export NOW="$(date +"%Y-%m-%d")" export DATA_DIR=/opt/dbb ...
  • 數據傾斜特征:個別Task處理大部分數據 後果:1.OOM;2.速度變慢,甚至變得慢的不可接受 常見原因: 數據傾斜的定位: 1.WebUI(查看Task運行的數據量的大小)。 2.Log,查看log中哪一行出現OOM,查找具體哪個Stage,進而確定哪一個shuffle產生了數據傾斜。 3.查看代 ...
  • vi dbbackup.sh在打開的編輯器輸入: 命令的意思是用mysqldump導出名為databasename的資料庫到/home/wwwroot/backup/文件夾並命名為date_日期.sql,-u後面的是你的Mysql的用戶名,-p後面的是Mysql密碼,databasename是要備份 ...
  • HAVING 子句 在 SQL 中增加 HAVING 子句原因是,WHERE 關鍵字無法與合計函數一起使用。 SQL HAVING 語法 SQL HAVING 實例 我們擁有下麵這個 "Orders" 表: O_IdOrderDateOrderPriceCustomer 1 2008/12/29 1 ...
  • 在MySQL中,無論是Innodb還是MyIsam,都使用了B+樹作索引結構(這裡不考慮hash等其他索引)。本文將從最普通的二叉查找樹開始,逐步說明各種樹解決的問題以及面臨的新問題,從而說明MySQL為什麼選擇B+樹作為索引結構。 ...
  • 本文鏈接: "Android MediaPlayer 倍速播放,調整播放速度" 現在市面上的很多音視頻App都有倍速播放的功能,例如把播放速度調整為0.5、1.5、2倍等等。 從Android API 23 (Android M)開始,MediaPlayer支持調整播放速度。 使用的方法是setPl ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...