最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
iOS開(kāi)發(fā)之MethodSwizzling深入淺出-創(chuàng)新互聯(lián)



創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的古冶網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

iOS開(kāi)發(fā)之 Method Swizzling 深入淺出

只要善用Google,網(wǎng)上有很多關(guān)于Method Swizzling的Demo,在這里我就不打算貼代碼了,主要介紹下概念,原理,注意事項(xiàng)等等。

開(kāi)發(fā)需求

如果產(chǎn)品經(jīng)理突然說(shuō):"在所有頁(yè)面添加統(tǒng)計(jì)功能,也就是用戶(hù)進(jìn)入這個(gè)頁(yè)面就統(tǒng)計(jì)一次"。我們會(huì)想到下面的一些方法:

  • 手動(dòng)添加

直接簡(jiǎn)單粗暴的在每個(gè)控制器中加入統(tǒng)計(jì),復(fù)制、粘貼、復(fù)制、粘貼...
上面這種方法太Low了,消耗時(shí)間而且以后非常難以維護(hù),會(huì)讓后面的開(kāi)發(fā)人員罵死的。

  • 繼承

我們可以使用繼承的方式來(lái)解決這個(gè)問(wèn)題。創(chuàng)建一個(gè)基類(lèi),在這個(gè)基類(lèi)中添加統(tǒng)計(jì)方法,其他類(lèi)都繼承自這個(gè)基類(lèi)。

然而,這種方式修改還是很大,而且定制性很差。以后有新人加入之后,都要囑咐其繼承自這個(gè)基類(lèi),所以這種方式并不可取。

  • Category

我們可以為UIViewController建一個(gè)Category,然后在所有控制器中引入這個(gè)Category。當(dāng)然我們也可以添加一個(gè)PCH文件,然后將這個(gè)Category添加到PCH文件中。

  • Method Swizzling

我們可以使用蘋(píng)果的“黑魔法”Method Swizzling,Method Swizzling本質(zhì)上就是對(duì)IMPSEL進(jìn)行交換。

先了解幾個(gè)概念

Selectors, Methods, & Implementations

Objective-C的運(yùn)行時(shí)中,selectors, methods, implementations 指代了不同概念,然而我們通常會(huì)說(shuō)在消息發(fā)送過(guò)程中,這三個(gè)概念是可以相互轉(zhuǎn)換的。 下面是蘋(píng)果 Objective-C Runtime Reference中的描述:

  • Selector(typedef struct objc_selector *SEL):在運(yùn)行時(shí) Selectors 用來(lái)代表一個(gè)方法的名字。Selector是一個(gè)在運(yùn)行時(shí)被注冊(cè)(或映射)的C類(lèi)型字符串。Selector由編譯器產(chǎn)生并且在當(dāng)類(lèi)被加載進(jìn)內(nèi)存時(shí)由運(yùn)行時(shí)自動(dòng)進(jìn)行名字和實(shí)現(xiàn)的映射。

  • Method(typedef struct objc_method *Method):方法是一個(gè)不透明的用來(lái)代表一個(gè)方法的定義的類(lèi)型。

  • Implementation(typedef id (*IMP)(id, SEL,...)):這個(gè)數(shù)據(jù)類(lèi)型指向一個(gè)方法的實(shí)現(xiàn)的最開(kāi)始的地方。該方法為當(dāng)前CPU架構(gòu)使用標(biāo)準(zhǔn)的C方法調(diào)用來(lái)實(shí)現(xiàn)。該方法的第一個(gè)參數(shù)指向調(diào)用方法的自身(即內(nèi)存中類(lèi)的實(shí)例對(duì)象,若是調(diào)用類(lèi)方法,該指針則是指向元類(lèi)對(duì)象(metaclass)。第二個(gè)參數(shù)是這個(gè)方法的名字selector,該方法的真正參數(shù)緊隨其后。

理解 selector, method, implementation 這三個(gè)概念之間關(guān)系的最好方式是:在運(yùn)行時(shí),類(lèi)(Class)維護(hù)了一個(gè)消息分發(fā)列表來(lái)解決消息的正確發(fā)送。每一個(gè)消息列表的入口是一個(gè)方法(Method),這個(gè)方法映射了一對(duì)鍵值對(duì),其中鍵值是這個(gè)方法的名字 selector(SEL),值是指向這個(gè)方法實(shí)現(xiàn)的函數(shù)指針 implementation(IMP)。 Method swizzling 修改了類(lèi)的消息分發(fā)列表使得已經(jīng)存在的 selector 映射了另一個(gè)實(shí)現(xiàn) implementation,同時(shí)重命名了原生方法的實(shí)現(xiàn)為一個(gè)新的 selector。

Method Swizzling原理

Method Swizzing是發(fā)生在運(yùn)行時(shí)的,主要用于在運(yùn)行時(shí)將兩個(gè)Method進(jìn)行交換,我們可以將Method Swizzling代碼寫(xiě)到任何地方,但是只有在這段Method Swilzzling代碼執(zhí)行完畢之后互換才起作用。

iOS開(kāi)發(fā)之 Method Swizzling 深入淺出

iOS開(kāi)發(fā)之 Method Swizzling 深入淺出

Method Swizzling 使用注意

類(lèi)簇設(shè)計(jì)模式

在iOS中NSNumber、NSArray、NSDictionary等這些類(lèi)都是類(lèi)簇(Class Clusters),一個(gè)NSArray的實(shí)現(xiàn)可能由多個(gè)類(lèi)組成。
所以如果想對(duì)NSArray進(jìn)行Swizzling,必須獲取到其“真身”進(jìn)行Swizzling,直接對(duì)NSArray進(jìn)行操作是無(wú)效的。

下面列舉了NSArray和NSDictionary本類(lèi)的類(lèi)名,可以通過(guò)Runtime函數(shù)取出本類(lèi)。

類(lèi)名 真身
NSArray __NSArrayI
NSMutableArray __NSArrayM
NSDictionary __NSDictionaryI
NSMutableDictionary __NSDictionaryM

注意要點(diǎn)

  • Swizzling應(yīng)該總在+load中執(zhí)行
  • Swizzling應(yīng)該總是在dispatch_once中執(zhí)行
  • Swizzling在+load中執(zhí)行時(shí),不要調(diào)用[super load]。如果多次調(diào)用了[super load],可能會(huì)出現(xiàn)“Swizzle無(wú)效”的假象,原理見(jiàn)下圖:

iOS開(kāi)發(fā)之 Method Swizzling 深入淺出

Swift 自定義類(lèi)中使用 Method Swizzling

要在 Swift 自定義類(lèi)中使用 Method Swizzling 有兩個(gè)必要條件:

  • 包含 Swizzle 方法的類(lèi)需要繼承自 NSObject
  • 需要 Swizzle 的方法必須有動(dòng)態(tài)屬性(dynamic attribute)

注:對(duì)于 Swift 的自定義類(lèi),因?yàn)槟J(rèn)并沒(méi)有使用 Objective-C 運(yùn)行時(shí),因此也沒(méi)有動(dòng)態(tài)派發(fā)的方法列表,所以如果要 Swizzle 的是 Swift 類(lèi)型的方法的話(huà),是需要將原方法和替換方法都加上 dynamic 標(biāo)記,以指明它們需要使用動(dòng)態(tài)派發(fā)機(jī)制。當(dāng)然類(lèi)也要繼承自 NSObject。

再注:下面這個(gè)例子使用了 Objective-C 的動(dòng)態(tài)派發(fā),對(duì)于 NSObject 的子類(lèi)(UIViewController)是可以直接使用的,并不是 Swift 中自定義的類(lèi),因此沒(méi)有加 dynamic 標(biāo)記也是可以的。

Method Swizzling 中 Objective-C 與 Swift 的異同

區(qū)別 Objective-C Swift
Runtime 頭文件 #import <objc/runtime.h> 不需要
Swizzling 調(diào)用處 load 方法 initialize 方法

注:load 方法只在 Objective-C 里有,而且不能在 Swift 里重載,不管怎么試都會(huì)報(bào)編譯錯(cuò)誤。接下來(lái)執(zhí)行 Swizzle 最好的地方就是 initialize了,這是調(diào)用第一個(gè)方法前的地方。

因?yàn)?Swizzling 會(huì)改變?nèi)譅顟B(tài),所以我們需要在運(yùn)行時(shí)采取一些預(yù)防措施。GCD 的dispatch_once 可以保證操作的原子性,確保代碼只被執(zhí)行一次,不管有多少個(gè)線(xiàn)程。

Method Swizzling 實(shí)際應(yīng)用

APM(應(yīng)用性能管理)

網(wǎng)絡(luò)監(jiān)控的原理,應(yīng)該就是hook NSURLConnection , NSURLSession。崩潰收集的原理,應(yīng)該就是hook NSException。

  • https://newrelic.com/ 國(guó)外行業(yè)老大
  • http://www.tingyun.com/ 國(guó)內(nèi)聽(tīng)云
  • http://www.oneapm.com/ 國(guó)內(nèi)OneAPM
  • http://apm.netease.com/ 國(guó)內(nèi)網(wǎng)易

國(guó)外資料

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線(xiàn),公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。


分享題目:iOS開(kāi)發(fā)之MethodSwizzling深入淺出-創(chuàng)新互聯(lián)
文章位置:http://fisionsoft.com.cn/article/cshshs.html