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使用方法的几个简单例子(转)的更多相关文章

  1. extern外部方法使用C#简单例子

    外部方法使用C#简单例子 1.增加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  2. Hibernate4.2.4入门(一)——环境搭建和简单例子

    一.前言 发下牢骚,这段时间要做项目,又要学框架,搞得都没时间写笔记,但是觉得这知识学过还是要记录下.进入主题了 1.1.Hibernate简介 什么是Hibernate?Hibernate有什么用? ...

  3. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  4. mysql定时任务简单例子

    mysql定时任务简单例子 ? 1 2 3 4 5 6 7 8 9     如果要每30秒执行以下语句:   [sql] update userinfo set endtime = now() WHE ...

  5. java socket编程开发简单例子 与 nio非阻塞通道

    基本socket编程 1.以下只是简单例子,没有用多线程处理,只能一发一收(由于scan.nextLine()线程会进入等待状态),使用时可以根据具体项目功能进行优化处理 2.以下代码使用了1.8新特 ...

  6. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  7. Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍

    引用自 :http://www.2cto.com/database/201307/224836.html   Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍 先假设有这么一个表 ...

  8. NHibernate的简单例子

    NHibernate的简单例子 @(编程) [TOC] 因为项目需求,搭了一个NHibernate的例子,中间遇到了一些问题,通过各种方法解决了,在这里记录一下最后的结果. 1. 需要的dll Com ...

  9. java 使用 comet4j 主动向客户端推送信息 简单例子

    [背景] 今天,一个前端的师弟问我怎样做实时聊天窗口,我毫不犹豫地说:在前台定时访问服务端呀!师弟默默地百度了一番,最后告诉我,有一种技术是后服务端动推送信息给客户端的,这种技术的名字叫comet,我 ...

随机推荐

  1. 【欧拉函数表】POJ2478-Farey Sequence

    [题目大意] 求∑φ(i)(1<=i<=N). [思路] 欧拉函数具有如下的重要推论: 当b是素数时 性质①若b|a,有φ(ab)=φ(a)*b: 性质②若b不|a,有φ(ab)=φ(a) ...

  2. iOS开发之指定UIView的某几个角为圆角

    我们知道, 如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角 ...

  3. Centos 6.5 优化 一些基础优化和安全设置

    原文链接:http://www.centoscn.com/CentosSecurity/CentosSafe/2015/0424/5263.html 本文 centos 6.5 优化 的项有18处: ...

  4. SSL和TSL的区别【转】

    SSL由从前的网景公司开发有1,2,3三个版本,但现在只使用版本3 TLS是SSL的标准化后的产物 有1.0 1.1 1.2三个版本 默认使用1.0 TLS1.0和SSL3.0几乎没有区别 事实上我们 ...

  5. HTML5:绘制图形

    canvas绘图通过属于 canvas 的 JavaScript 方法完成 针对不支持html5的IE浏览器 <!--[if IE]> <script type="text ...

  6. Asp.Net生命周期和Http管道技术

    本篇主要介绍一下内容: 1.ASP.NET生命周期 2.Http运行时 3.Http管道技术 a)inetinfo.exe b)asp.net_isapi.dll c)aspnet_wp.exe d) ...

  7. js时间小总结

    1.js获取时间 var myDate = new Date(); 1 myDate.getYear(); //获取当前年份(2位) 2 myDate.getFullYear(); //获取完整的年份 ...

  8. python socket timeout设置

    需要在调用socket的connect方法之前设置settimeout(time)方法,另外在设置之后要将再次调用settimeout(None)来设置socket进入阻塞模式. 如下代码示例: so ...

  9. Less资源汇总

    GUI编译工具 为方便起见,建议初学者使用GUI编译工具来编译.less文件,以下是一些可选GUI编译工具: koala(Win/Mac/Linux) 国人开发的LESSCSS/SASS编译工具.下载 ...

  10. Android使用tcpdump抓包

    AllJoyn中有个问题:Server切换到Client后,重新加入其他Server时join session会失败,原因是timeout(join session是异步的,在指定时间内没有收到回应) ...