[iOS]在运行时为类添加方法
2016-04-06 14:07
357 查看
http://longtimenoc.com/archives/ios%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E4%B8%BA%E7%B1%BB%E6%B7%BB%E5%8A%A0%E6%96%B9%E6%B3%95 Obj-C用起来真是各种happy,比如现在有这样一种情况:有一个类,我们希望它能响应一个消息(message),但是这个类没有相应的方法(method),而你又偏偏不能重写/继承这个类。这时我们可能会想到,能不能动态地给类添加一个方法呢?感谢Obj-C,仅需简单几步就能实现。 先看一段代码 #if TARGET_IPHONE_SIMULATOR #import <objc/objc-runtime.h> #else #import <objc/runtime.h> #import <objc/message.h> #endif @interface EmptyClass:NSObject @end @implementation EmptyClass @end void sayHello(id self, SEL _cmd) { NSLog(@"Hello"); } - (void)addMethod { class_addMethod([EmptyClass class], @selector(sayHello2), (IMP)sayHello, "v@:"); // Test Method EmptyClass *instance = [[EmptyClass alloc] init]; [instance sayHello2]; [instance release]; } 我们首先定义了一个EmptyClass,继承NSObject,没有任何自带方法,接着定义了一个函数。这里提一句,Obj-C的方法(method)就是一个至少需要两个参数(self,_cmd)的C函数,这个函数仅仅输出一句Hello。接下来在addMethod方法中,我们调用class_addMethod()为EmptyClass添加方法,class_addMethod()是这样定义的: BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) 参数说明: cls:被添加方法的类 name:可以理解为方法名,这个貌似随便起名,比如我们这里叫sayHello2 imp:实现这个方法的函数 types:一个定义该函数返回值类型和参数类型的字符串,这个具体会在后面讲 接着创建EmptyClass的实例,调用sayHello2,运行,输出Hello,添加方法成功。 接下来说一下types参数, 比如我们要添加一个这样的方法:-(int)say:(NSString *)str; 相应的实现函数就应该是这样: int say(id self, SEL _cmd, NSString *str) { NSLog(@"%@", str); return 100;//随便返回个值 } class_addMethod这句就应该这么写: class_addMethod([EmptyClass class], @selector(say:), (IMP)say, "i@:@"); 其中types参数为"i@:@“,按顺序分别表示: i:返回值类型int,若是v则表示void @:参数id(self) ::SEL(_cmd) @:id(str) 这些表示方法都是定义好的(Type Encodings),关于Type Encodings的其他类型定义请参考官方文档 最后调用say:方法: int a = [instance say:@"something"]; NSLog(@"%d", a); 输出something和100。 关于本文所涉及内容的详细信息请参考Objective-C Runtime Reference 本文参考了: Add Methods at Runtime in Objective-C(原文的class_addMethods已经废弃了) The Coolest iOS Hack 推荐去看看 —以上—
相关文章推荐
- iOS开发 cocopods详细使用
- iOS开发 cocopods使用详解
- ios开发--高德地图SDK使用简介
- 企业级iOS应用开发实战(看书笔记)
- [ios]使用Masonry为自定义view添加约束时,得先把自定义view添加到父视图上
- iOS 开发证书显示 此证书签发者无效 解决办法
- iOS报错 - If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variabl
- iOS 知识点相同和不同之处
- iOS视频播放(二)整理
- iOS终端常用命令总结
- iOS 注册Xib注册总结
- iOS Xib关联错误导致的问题
- 【iOS开发】打包静态库.a文件
- iOS开发之详解连连支付集成
- iOS开发使用TPKeyboardAvoiding解决键盘被遮挡
- IOS开发数据存储篇—IOS中的几种数据存储方式
- iOS的开发内购全套图文教程
- IOS视图层次结构
- iOS:常见错误总结
- Bison眼中的iOS开发多线程是这样的(三)