objc_runtime使用方法的几个简单例子
2013-04-18 09:49
501 查看
1. 给NSObject类动态添加属性
h定义部分@interface UIWebView (LoadProgress) @property (nonatomic, assign) NSInteger resourceCount; @end
m实现部分
首先要定义一个全局的key
// resourceCount object keys static void *s_resourceCountKey = &s_resourceCountKey; //static void *s_resourceCountKey = "s_resourceCountKey";
初始
@implementation UIWebView (LoadProgress) @dynamic resourceCount;
实现
#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
基本替换方法// 替换类方法 // 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; }
新方法定义
// 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中
+ (void)load { s_UIWebView__identifierForInitialRequest_Imp = (id (*)(id, SEL, id, id, id))HLSSwizzleSelector(self, @selector(webView:identifierForInitialRequest:fromDataSource:), (IMP)swizzled_UIWebView__identifierForInitialRequest_Imp); }
实现部分
#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中// [self implementsProtocol:@protocol(UIActionSheetDelegate)]
// 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; }
相关文章推荐
- objc_runtime使用方法的几个简单例子(转)
- HttpClient 4使用方法的几个例子(代理,StringEntity字符串数据,文件上传)(转载)
- 一个例子了解apacheBench的简单使用方法
- File对象相关方法使用简单例子
- HttpClient 4使用方法的几个例子
- HttpClient 4使用方法的几个例子
- HttpClient 4使用方法的几个例子
- WinForm常用的几个控件的简单使用方法
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- 获取命令使用的方法和几个简单的操作命令
- extern外部方法使用C#简单例子
- 几个简单的jQuery使用方法
- extern外部方法使用C#简单例子
- runtime使用时-交叉方法简单使用
- HttpClient 4使用方法的几个例子
- 使用Runtime.getRuntime().exec()方法的几个陷阱 (转)
- JQuery 中简单的几个 类选择器 使用方法
- web.config文件自定义配置节的使用方法的一个简单例子
- web.config文件自定义配置节的使用方法的一个简单例子
- 海量数据处理实例--几个使用bit-map的简单例子