objc_runtime使用方法的几个简单例子(转)
1. 给NSObject类动态添加属性
h定义部分
[cpp]
@interface UIWebView (LoadProgress)
@property (nonatomic, assign) NSInteger resourceCount;
@end
@interface UIWebView (LoadProgress)
@property (nonatomic, assign) NSInteger resourceCount;
@end
m实现部分
首先要定义一个全局的key
[cpp]
// resourceCount object keys
static void *s_resourceCountKey = &s_resourceCountKey;
//static void *s_resourceCountKey = "s_resourceCountKey";
// resourceCount object keys
static void *s_resourceCountKey = &s_resourceCountKey;
//static void *s_resourceCountKey = "s_resourceCountKey";
初始
[cpp]
@implementation UIWebView (LoadProgress)
@dynamic resourceCount;
@implementation UIWebView (LoadProgress)
@dynamic resourceCount;
实现
[cpp]
#pragma mark Accessors and mutators
- (NSInteger)resourceCount
{
NSNumber *resourceCountNumber = objc_getAssociatedObject(self, s_resourceCountKey);
if (! resourceCountNumber)
{
return 0;
}
else
{
return [resourceCountNumber integerValue];
}
}
- (void)setResourceCount:(NSInteger)rCount
{
objc_setAssociatedObject(self, s_resourceCountKey, [NSNumber numberWithInteger:rCount], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark Accessors and mutators
- (NSInteger)resourceCount
{
NSNumber *resourceCountNumber = objc_getAssociatedObject(self, s_resourceCountKey);
if (! resourceCountNumber)
{
return 0;
}
else
{
return [resourceCountNumber integerValue];
}
}
- (void)setResourceCount:(NSInteger)rCount
{
objc_setAssociatedObject(self, s_resourceCountKey, [NSNumber numberWithInteger:rCount], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
这样就可以直接使用了
webView.resourceCount = 10;
2. 给NSObject类动态添加代理protocol
同属性
动态创建代理暂时先不写了
3. 替换或变更NSObject类方法Method
基本替换方法
[cpp]
// 替换类方法
// frome: CoconutKit
IMP HLSSwizzleClassSelector(Class clazz, SEL selector, IMP newImplementation)
{
// Get the original implementation we are replacing
Class metaClass = objc_getMetaClass(class_getName(clazz));
Method method = class_getClassMethod(metaClass, selector);
IMP origImp = method_getImplementation(method);
if (! origImp) {
return NULL;
}
class_replaceMethod(metaClass, selector, newImplementation, method_getTypeEncoding(method));
return origImp;
}
// 替换实例方法
IMP HLSSwizzleSelector(Class clazz, SEL selector, IMP newImplementation)
{
// Get the original implementation we are replacing
Method method = class_getInstanceMethod(clazz, selector);
IMP origImp = method_getImplementation(method);
if (! origImp) {
return NULL;
}
class_replaceMethod(clazz, selector, newImplementation, method_getTypeEncoding(method));
return origImp;
}
// 替换类方法
// frome: CoconutKit
IMP HLSSwizzleClassSelector(Class clazz, SEL selector, IMP newImplementation)
{
// Get the original implementation we are replacing
Class metaClass = objc_getMetaClass(class_getName(clazz));
Method method = class_getClassMethod(metaClass, selector);
IMP origImp = method_getImplementation(method);
if (! origImp) {
return NULL;
}
class_replaceMethod(metaClass, selector, newImplementation, method_getTypeEncoding(method));
return origImp;
}
// 替换实例方法
IMP HLSSwizzleSelector(Class clazz, SEL selector, IMP newImplementation)
{
// Get the original implementation we are replacing
Method method = class_getInstanceMethod(clazz, selector);
IMP origImp = method_getImplementation(method);
if (! origImp) {
return NULL;
}
class_replaceMethod(clazz, selector, newImplementation, method_getTypeEncoding(method));
return origImp;
}
新方法定义
[cpp]
// Original implementation of the methods we swizzle
static id (*s_UIWebView__identifierForInitialRequest_Imp)(id, SEL, id, id, id) = NULL;
// Swizzled method implementations
static id swizzled_UIWebView__identifierForInitialRequest_Imp(UIWebView *self, SEL _cmd, id webView, id initialRequest, id dataSource);
// Original implementation of the methods we swizzle
static id (*s_UIWebView__identifierForInitialRequest_Imp)(id, SEL, id, id, id) = NULL;
// Swizzled method implementations
static id swizzled_UIWebView__identifierForInitialRequest_Imp(UIWebView *self, SEL _cmd, id webView, id initialRequest, id dataSource);
方法初始化需要写在类方法+ (void)load中
[cpp]
+ (void)load
{
s_UIWebView__identifierForInitialRequest_Imp = (id (*)(id, SEL, id, id, id))HLSSwizzleSelector(self, @selector(webView:identifierForInitialRequest:fromDataSource:), (IMP)swizzled_UIWebView__identifierForInitialRequest_Imp);
}
+ (void)load
{
s_UIWebView__identifierForInitialRequest_Imp = (id (*)(id, SEL, id, id, id))HLSSwizzleSelector(self, @selector(webView:identifierForInitialRequest:fromDataSource:), (IMP)swizzled_UIWebView__identifierForInitialRequest_Imp);
}
实现部分
[cpp]
#pragma mark Swizzled method implementations
static id swizzled_UIWebView__identifierForInitialRequest_Imp(UIWebView *self, SEL _cmd, id webView, id initialRequest, id dataSource)
{
// 调用原方法
(*s_UIWebView__identifierForInitialRequest_Imp)(self, _cmd, webView, initialRequest, dataSource);
[self setResourceCount:self.resourceCount+1];
return [NSNumber numberWithInteger:self.resourceCount];
}
#pragma mark Swizzled method implementations
static id swizzled_UIWebView__identifierForInitialRequest_Imp(UIWebView *self, SEL _cmd, id webView, id initialRequest, id dataSource)
{
// 调用原方法
(*s_UIWebView__identifierForInitialRequest_Imp)(self, _cmd, webView, initialRequest, dataSource);
[self setResourceCount:self.resourceCount+1];
return [NSNumber numberWithInteger:self.resourceCount];
}
4. 代理方法检索
可直接定义到NSObject的Category中
[cpp]
// [self implementsProtocol:@protocol(UIActionSheetDelegate)]
// [self implementsProtocol:@protocol(UIActionSheetDelegate)][cpp] view plaincopyprint?
// frome: CoconutKit
- (BOOL)implementsProtocol:(Protocol *)protocol
{
// Only interested in optional methods. Required methods are checked at compilation time
unsigned int numberOfMethods = 0;
struct objc_method_description *methodDescriptions = protocol_copyMethodDescriptionList(protocol, NO /* optional only */, YES, &numberOfMethods);
for (unsigned int i = 0; i < numberOfMethods; ++i) {
struct objc_method_description methodDescription = methodDescriptions[i];
SEL selector = methodDescription.name;
if (! class_getInstanceMethod([self class], selector)) {
NSString *selectorString = [NSString stringWithCString:sel_getName(selector) encoding:NSUTF8StringEncoding];
NSString *protocolName = [NSString stringWithCString:protocol_getName(protocol) encoding:NSUTF8StringEncoding];
HLSLoggerInfo(@"Class %@ does not implement method %@ of protocol %@", [self className], selectorString, protocolName);
selectorString = nil; // Just to remove unused variable warnings
protocolName = nil;
return NO;
}
}
return YES;
}
// frome: CoconutKit
- (BOOL)implementsProtocol:(Protocol *)protocol
{
// Only interested in optional methods. Required methods are checked at compilation time
unsigned int numberOfMethods = 0;
struct objc_method_description *methodDescriptions = protocol_copyMethodDescriptionList(protocol, NO /* optional only */, YES, &numberOfMethods);
for (unsigned int i = 0; i < numberOfMethods; ++i) {
struct objc_method_description methodDescription = methodDescriptions[i];
SEL selector = methodDescription.name;
if (! class_getInstanceMethod([self class], selector)) {
NSString *selectorString = [NSString stringWithCString:sel_getName(selector) encoding:NSUTF8StringEncoding];
NSString *protocolName = [NSString stringWithCString:protocol_getName(protocol) encoding:NSUTF8StringEncoding];
HLSLoggerInfo(@"Class %@ does not implement method %@ of protocol %@", [self className], selectorString, protocolName);
selectorString = nil; // Just to remove unused variable warnings
protocolName = nil;
return NO;
}
}
return YES;
}
http://www.2cto.com/kf/201304/204393.html
objc_runtime使用方法的几个简单例子(转)的更多相关文章
- extern外部方法使用C#简单例子
外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...
- Hibernate4.2.4入门(一)——环境搭建和简单例子
一.前言 发下牢骚,这段时间要做项目,又要学框架,搞得都没时间写笔记,但是觉得这知识学过还是要记录下.进入主题了 1.1.Hibernate简介 什么是Hibernate?Hibernate有什么用? ...
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答
一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...
- mysql定时任务简单例子
mysql定时任务简单例子 ? 1 2 3 4 5 6 7 8 9 如果要每30秒执行以下语句: [sql] update userinfo set endtime = now() WHE ...
- java socket编程开发简单例子 与 nio非阻塞通道
基本socket编程 1.以下只是简单例子,没有用多线程处理,只能一发一收(由于scan.nextLine()线程会进入等待状态),使用时可以根据具体项目功能进行优化处理 2.以下代码使用了1.8新特 ...
- 一个简单例子:贫血模型or领域模型
转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...
- Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
引用自 :http://www.2cto.com/database/201307/224836.html Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍 先假设有这么一个表 ...
- NHibernate的简单例子
NHibernate的简单例子 @(编程) [TOC] 因为项目需求,搭了一个NHibernate的例子,中间遇到了一些问题,通过各种方法解决了,在这里记录一下最后的结果. 1. 需要的dll Com ...
- java 使用 comet4j 主动向客户端推送信息 简单例子
[背景] 今天,一个前端的师弟问我怎样做实时聊天窗口,我毫不犹豫地说:在前台定时访问服务端呀!师弟默默地百度了一番,最后告诉我,有一种技术是后服务端动推送信息给客户端的,这种技术的名字叫comet,我 ...
随机推荐
- 十. 图形界面(GUI)设计8.选择框和单选按钮
选择框.单选框和单选按钮都是选择组件,选择组件有两种状态,一种是选中(on),另一种是未选中(off),它们提供一种简单的 “on/off”选择功能,让用户在一组选择项目中作选择. 选择框 选择框(J ...
- jdk_配置
如果不知道jdk安装目录,可以使用如下命令查找到jdk安装目录 linux /usr/libexec/java_home windows版 新建系统变量JAVA_HOME(自己jdk的安装目录)C:\ ...
- RxJava 2.x 理解-3
背压:Flowable / Subscriber 在RxJava 1.x 理解 中,没有讲到背压这个概念,是因为学习太落后了,RxJava都出2了,所以直接在2上学. 背压是下游控制上游流速的一种手段 ...
- RxJava 2.x 理解-2
操作符总结: http://reactivex.io/documentation/operators.html https://github.com/ReactiveX/RxJava/wiki Ope ...
- 国内流行的开源.net微信公众平台SDK对比分析
一.引言 目前微信公众平台正如火如荼的进行中,微信虽然在海外市场不敌WhatsApp,但是已经俘获了国内绝大部分用户的心.作为国内最大的,超级"app",微信已算是成功问鼎了.公众 ...
- Redis的安装与idea中的使用
一.Redis的安装 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开 ...
- zk client获取数据
获取数据 它返回znode的关联数据和指定znode的元数据.你将获得信息,例如上次修改数据的时间,修改的位置以及数据的相关信息.此CLI还用于分配监视器以显示数据相关的通知. 语法 get /pat ...
- CSS3:绘制图形
CSS画图形,基本上所有的实现都是对边框的角度的调整及组合. 以下不包含兼容浏览器的前缀,请使用时在border-radius前加-moz-.-webkit- .... 1.正常得不得了的矩形 .sq ...
- codeforces round #264(div2)
A题 我仅仅想说题意非常坑,一不小心就会wa,哎,不机智的我居然在最后判题的过程中错了,少加一个推断语句. 错的值了,你说呢? #include<map> #include<cm ...
- 使用Python开发SQLite代理服务器(转载)
转载:https://mp.weixin.qq.com/s?timestamp=1498531736&src=3&ver=1&signature=Eq6DPvkuGJi*G5s ...