hook的使用

OC runtime 提供了动态替换Method 实现的能力,加上category的使用,可以实现一种叫 swizzle的技术,从而给问题定位提供了一种方法。

举个例子,NSNotificationCenter 注册的observer 是通过assign 方法保留observer引用(而不是weak 或 retain、strong),这样的话如果某个observer只是注册而没有注销,那么这个observer释放后,NSNotificationCenter 发送通知时将找不到这个observer,因为这个observer已经成了野指针,从而发生crash。

那么到底是那个observer 只注册而没有注销呢? 可以通过给 NSNotificationCenter 增加一个category ,在category中通过swizzle 给原来的注册与注销方法添加log 来查看。

category的头文件:

增加了swizzle 类方法,在app 启动时调用

/*
* NSNotificationCenter+TestHook.h
*/

#import <Foundation/Foundation.h>

@interface NSNotificationCenter (TestHook)

+ (void) swizzle;
@end

实现,增加两个hook 方法,分别给注册和注销方法添加log:

注意hook方法不能在头文件暴露以防被直接调用,因为在使用method_exchangeImplimentaions之前,直接调用会发生递归。

#import "NSNotificationCenter+TestHook.h"
#import <objc/runtime.h>

@implementation NSNotificationCenter (TestHook)

-(void)hook_addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject{
    NSLog(@"====== add observer for:%@, selector: %s, class %s", aName, sel_getName(aSelector), class_getName([observer class]));
    [self hook_addObserver:observer selector:aSelector name:aName object:anObject];
}

- (void)hook_removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject{
        NSLog(@"====== remove observer for:%@,  class %s", aName, class_getName([observer class]));
    [self hook_removeObserver:observer name:aName object:anObject];
    
}

+(void)swizzle{
    Method ori_Method =  class_getInstanceMethod([NSNotificationCenter class], @selector(addObserver:selector:name:object:));
    Method my_Method = class_getInstanceMethod([NSNotificationCenter class], @selector(hook_addObserver:selector:name:object:));
    
    method_exchangeImplementations(ori_Method, my_Method);
    
    Method ori_remove = class_getInstanceMethod([NSNotificationCenter class], @selector(removeObserver:name:object:));
    Method my_remove = class_getInstanceMethod([NSNotificationCenter class], @selector(hook_removeObserver:name:object:));
    method_exchangeImplementations(ori_remove, my_remove);
    
}

@end

然后在应用AppDelegeate中调用 :

....
#import "NSNotificationCenter+TestHook.h"
...

@implementation MyAppDelegate

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

...

 [NSNotificationCenter swizzle];

...

}

...

@end

这样就能清楚的看到哪些observer注册了哪些通知,以及在什么时候注销了通知。

时间: 2024-10-11 23:02:56

hook的使用的相关文章

HOOK钩子技术5 SSDT Inline Hook

原理 内联钩子的原理在R3和R0下是相同的,就是不改变SSDT表项,而是改变函数内部前几条指令. 内联钩子的典型伪函数为: 恢复原指令 执行目标操作,或改写参数 执行原函数 返回时重新挂钩 demo #include "stdafx.h" #ifdef __cplusplus extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

HDU 1689 Just a Hook 线段树区间更新求和

点击打开链接 Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18894    Accepted Submission(s): 9483 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible

hdu 1698 Just a Hook(线段树,成段更新,懒惰标记)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18384    Accepted Submission(s): 9217 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing

svn集成ReviewBoard,让post-commit hook后台运行

代码评审(Code Review)不但可以提高质量,而且还是一个知识共享和指导的极好的手段. 代码评审(CodeReview)一般有两种形式:pre-commit-review,post-commit-review. pre-commit-review是指代码提交到代码库前进行代码评审: post-commit-review是指代码提交到代码库后进行代码评审. ReviewBoard是一个开源的基于web的代码评审工具,支持Subversion,CVS,Git和Mercurial版本控制系统.

gitlab+jenkins+hook代码自动构建发布上线

Gitlab+Jenkins+Hook 1.gitlab和jenkins的安装见: http://www.cnblogs.com/cuishuai/p/7544663.html http://www.cnblogs.com/cuishuai/p/7544775.html 2.gitlab配置 1)创建一个project,并创建一个monkey的分支. 2)对分支进行设置: 点击project->settings->integrations: 1. 2. 3 Webhook,点击test,返回如

android hook 框架 libinject2 简介、编译、运行

简介: libinject 最开始是2011年看雪android安全版版主之一‘古河’大神发布的一份android平台的注入库:  发个Android平台上的注入代码  ,网上很多随后发布的注入代码都是其变种,不过我这几天尝试运行那份代码,发现有些问题,本博运行和分析的代码是另外一位大神的改进版本,在我的环境里运行注入和挂钩都成功了 : Android中的so注入(inject)和挂钩(hook) - For both x86 and arm ,为了表示区别,我把这个项目称为  libinjec

&lt;BEA-000388&gt; &lt;JVM called WLS shutdown hook. The server will force shutdown now&gt;

在生产weblogic部署环境,发现weblogic每隔几个小时就shutdown一次,经过跟踪发现既不是内存问题,也不是数据库连接池问题,更不是访问量过大引起. 查询相关日志,只有以下几句shutdown的日志: <BEA-000388> <JVM called WLS shutdown hook. The server will force shutdown now> <BEA-000396> <Server shutdown has been request

WordPress中函数钩子hook的作用及基本用法

WordPress 的插件机制实际上只的就是这个 Hook 了,它中文被翻译成钩子,允许你参与 WordPress 核心的运行,是一个非常棒的东西,下面我们来详细了解一下它.钩子分类 钩子分为两种,一种叫做动作(action),还有一种叫做过滤器(filter).这两种钩子实现原理基本一样,后边会讲到,使用上的区别在于过滤器有返回值,而动作没有. 动作的理念是让你在一种情况或者一个特别的位置执行一些函数,比如发送一封邮件等:过滤器则是让你修改 WordPress 核心需要用到的一个值,然后 Wo

线段树专题—HDU1698 Just a Hook

题意:t组数据,给一个n.m表示n长度的钩和m次操作.初始钩子的每单位长度的价值为1,接下来输入 x,y,k 的操作把钩子[x,y]区间的价值替换为k,求m次操作后钩子的价值为多少 分析:成段替换.最后仅仅要求第一个区间就能够了,使用不用写query询问 代码: #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm>

libjohn hook系统函数导致的NE问题分析

一段时间,发现某个机型上一些系统级APP高概率出现NE,现场如下: pid: 20335, tid: 20335, name: m.xxx.market >>> com.xxx.market <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000140 r0 75bf67f8 r1 bec44e10 r2 41526558 r3 00000000 r4 41524fa8 r5 00000000 r6