最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS中實現(xiàn)檢測Zoombie對象的具體方法

 更新時間:2018年01月05日 10:49:24   作者:commer_cocoa  
這篇文章主要給大家介紹了關(guān)于iOS中實現(xiàn)檢測Zoombie對象的具體方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

我們大家都知道,如果在XCode中開啟了Zoombie Objects。如圖。

那么在一個對象釋放后,再次給該對象發(fā)送消息,在Xcode控制臺中,可看到如下打印信息。這些信息可以幫助我們定位問題。

ZoombieDemo[12275:2841478] *** -[Test test]: message sent to deallocated instance 0x60800000b000

那么究竟XCode是如何實現(xiàn)僵尸對象的檢查的,我們將來一一揭曉。

實現(xiàn)原理

在《Effective Objective-C 》一書中有提到過僵尸指針的實現(xiàn)方式。

通過hook NSObject的dealloc的方法,在一個對象要釋放的時候,通過objcduplicateClass復(fù)制NSZombie類,生成NSZombieOriginaClass,并且將當(dāng)前對象的isa指向新生成的類。這塊內(nèi)存不會釋放。

因為在給該對象發(fā)消息時,NSZombieOriginaClass并未實現(xiàn)原有類的方法,所以會走完整的消息轉(zhuǎn)發(fā)。所以我們能取出具體的OriginaClass(去掉NS_Zombie),當(dāng)前sel,打印出來。

[class seletor]:message sent to deallocated instance 0x22909"

簡單來說,就是將對象指向一個新的類,因為新類里面并沒有原有類方法的實現(xiàn),所以必定會走到消息轉(zhuǎn)發(fā)中。

以上說的是動態(tài)生成新的類,類名是通過固定前綴拼接而成,將isa指向該類。其實還有一種方式,就是指向固定的類,原有類名通過關(guān)聯(lián)對象的方式來存儲。

既然知道了原理,可以動手實現(xiàn)一下。

動手實現(xiàn)

首先是hook dealloc方法。在NSObject+HookDealloc中實現(xiàn)。

+ (void)load {
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
  Class class = [self class];
  SEL originalSelector = NSSelectorFromString(@"dealloc");
  SEL swizzledSelector = @selector(swizzledDealloc);
  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);
  }
 });
}

動態(tài)生成新的類

在swizzledDealloc中,我們通過"Zoombie_"拼接原始類名,得到一個新的類名。然后生成該類,添加 forwardingTargetForSelector的實現(xiàn)。便于在消息轉(zhuǎn)發(fā)的時候得到調(diào)用信息。

NSString *Zoombie_Class_Prefix = @"Zoombie_";
// 指向動態(tài)生成的類,用Zoombie拼接原有類名
NSString *className = NSStringFromClass([self class]);
NSString *zombieClassName = [Zoombie_Class_Prefix stringByAppendingString: className]; 
Class zombieClass = NSClassFromString(zombieClassName);
if(zombieClass) return; 
zombieClass = objc_allocateClassPair([NSObject class], [zombieClassName UTF8String], 0); 
objc_registerClassPair(zombieClass);
class_addMethod([zombieClass class], @selector(forwardingTargetForSelector:), (IMP)forwardingTargetForSelector, "@@:@");
object_setClass(self, zombieClass);

forwardingTargetForSelector的方法實現(xiàn),原始類名,去掉前綴即可得到。因為這里已經(jīng)是調(diào)用到已釋放對象的方法,我們直接abort掉,程序?qū)⒈罎ⅰ?/p>

id forwardingTargetForSelector(id self, SEL _cmd, SEL aSelector) {
 NSString *className = NSStringFromClass([self class]);
 NSString *realClass = [className stringByReplacingOccurrencesOfString:Zoombie_Class_Prefix withString:@""];
 NSLog(@"[%@ %@] message sent to deallocated instance %@", realClass, NSStringFromSelector(aSelector), self);
 abort();
}

指向固定類

指向已有的ZoombieObject類,類名存在關(guān)聯(lián)對象中。

 // 指向固定的類,原有類名存儲在關(guān)聯(lián)對象中
NSString *originClassName = NSStringFromClass([self class]);
objc_setAssociatedObject(self, "OrigClassNameKey", originClassName, OBJC_ASSOCIATION_COPY_NONATOMIC);
object_setClass(self, [ZoombieObject class]);

同上,在ZoombieObject中實現(xiàn)forwardingTargetForSelector方法,可以得到調(diào)用信息。原始類名通過關(guān)聯(lián)對象獲取。

- (id)forwardingTargetForSelector:(SEL)aSelector {
 NSLog(@"[%@ %@] message sent to deallocated instance %@", objc_getAssociatedObject(self, "OrigClassNameKey"), NSStringFromSelector(aSelector), self);
 abort();
}

forwardingTargetForSelector是消息轉(zhuǎn)發(fā)的第二步,我們也可以不在這里處理,等到最后一步forwardInvocation,不過要生成方法簽名,要略微復(fù)雜些。

要想走到forwardInvocation,methodSignatureForSelector返回不能是空。這里我們返回了StubProxy類中stub的方法簽名(已經(jīng)定義好的類和方法),最后就回走到forwardInvocation,通過invocation.selector可得到當(dāng)前調(diào)用方法名。通過關(guān)聯(lián)對象獲取到原始類名。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
 NSMethodSignature *sig = [super methodSignatureForSelector:aSelector];
 if (!sig) {
  sig = [StubProxy instanceMethodSignatureForSelector:@selector(stub)];
 } 
 return sig;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
 NSLog(@"[%@ %@] message sent to deallocated instance %@", objc_getAssociatedObject(self, "OrigClassNameKey"), NSStringFromSelector(anInvocation.selector), self);
}

這樣,一個簡單的檢測僵尸指針的方案就實現(xiàn)了。

demo在此。

兩種方式都實現(xiàn)了,可通過調(diào)整NSObject+HookDealloc中,swizzledSelector的值來切換。my_dealloc是指向動態(tài)類,swizzledDealloc是指向固定類。

SEL swizzledSelector = @selector(my_dealloc);

在App運行起來后,點擊button,即可觸發(fā)。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • iOS倒計時的實現(xiàn)方法

    iOS倒計時的實現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了iOS倒計時的實現(xiàn)方法,點擊進行倒計時準(zhǔn)備,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • iOS沙盒視頻縮略圖及保存本地代碼

    iOS沙盒視頻縮略圖及保存本地代碼

    這篇文章主要為大家詳細(xì)介紹了iOS沙盒視頻縮略圖及保存本地的代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • iOS中tableview實現(xiàn)編輯、全選及刪除等功能的方法示例

    iOS中tableview實現(xiàn)編輯、全選及刪除等功能的方法示例

    這篇文章主要給大家介紹了關(guān)于iOS中tableview實現(xiàn)編輯、全選及刪除等功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),不僅是介紹實現(xiàn)的方法,將實現(xiàn)過程中遇到的問題也都分享出來了,需要的朋友們下面來一起看看吧。
    2017-07-07
  • iOS 純代碼寫個側(cè)滑欄功能

    iOS 純代碼寫個側(cè)滑欄功能

    下面小編就為大家分享一篇iOS 純代碼寫個側(cè)滑欄功能,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 淺談iOS開發(fā)如何適配暗黑模式(Dark Mode)

    淺談iOS開發(fā)如何適配暗黑模式(Dark Mode)

    這篇文章主要介紹了淺談iOS開發(fā)如何適配暗黑模式(Dark Mode),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • iOS實現(xiàn)調(diào)用QQ客戶端發(fā)起臨時會話

    iOS實現(xiàn)調(diào)用QQ客戶端發(fā)起臨時會話

    本篇文章主要給大家詳細(xì)分析了用IOS實現(xiàn)調(diào)用QQ客戶端發(fā)起臨時會話的功能,對此有需要的朋友收藏分享下。
    2018-02-02
  • IOS  Swift3 四種單例模式詳解及實例

    IOS Swift3 四種單例模式詳解及實例

    這篇文章主要介紹了IOS Swift3 四種單例模式詳解及實例的相關(guān)資料,這里對四種單例模式進行了實例介紹 ,需要的朋友可以參考下
    2016-12-12
  • ios的簽名機制詳解

    ios的簽名機制詳解

    這篇文章主要介紹了ios的簽名機制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用ios開發(fā),感興趣的朋友可以了解下
    2021-04-04
  • IOS 網(wǎng)絡(luò)請求中設(shè)置cookie

    IOS 網(wǎng)絡(luò)請求中設(shè)置cookie

    這篇文章主要介紹了IOS 網(wǎng)絡(luò)請求中設(shè)置cookie的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • iOS中的線程死鎖實例詳解

    iOS中的線程死鎖實例詳解

    這篇文章主要給大家介紹了關(guān)于iOS中線程死鎖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09

最新評論

黎平县| 尉犁县| 中阳县| 平遥县| 霍林郭勒市| 盐津县| 塘沽区| 丰都县| 盐山县| 宝山区| 宁乡县| 买车| 三亚市| 疏勒县| 铜鼓县| 永胜县| 云安县| 静宁县| 叶城县| 武功县| 北京市| 红原县| 萨嘎县| 杭州市| 桐庐县| 博客| 平江县| 河西区| 潜江市| 柯坪县| 莫力| 青阳县| 改则县| 南华县| 安塞县| 宣汉县| 尖扎县| 西盟| 武隆县| 光山县| 响水县|