Runtime的简单使用
来源:互联网 发布:java代码生成jar包 编辑:程序博客网 时间:2024/05/20 23:38
Runtime的简单使用
Runtime一直都是iOS开发者讨论的比较多的问题,如果不知道一点点Runtime的使用的话,感觉都不好意思说自己是一个用OC来开发Apple应用的开发人员。虽然Runtime使用的这类博客在网上可以说是烂大街了,但是我还是想记录一下自己对Runtime的学习情况。
在OC中使用Runtime需要导入#import <objc/objc-runtime.h>,而在Swift中则不需要,系统已经为我们导入了
一、消息发送
objc_msgSend(<#id self#>, <#SEL op, ...#>)要使用这个方法,在Xcode7以上需要修改下设置信息:targets --> Build settings --> 搜索 msg 修改为 NO 即可索引出该方法
- (void)viewDidLoad { [super viewDidLoad]; objc_msgSend(self, @selector(msgSend:param2:), @"param1", @"param2");}- (void)msgSend:(NSString *)param1 param2:(NSString *)param2{ NSLog(@"param1 = %@, param2 = %@",param1, param2);}但是在swift中已经没有这个方法了
二、获取属性名、属性的值
获取成员属性名和值
- (NSDictionary *)getPropertyListAndValue{ NSMutableDictionary * dic = [NSMutableDictionary dictionary]; unsigned int count = 0; Ivar * ivar = class_copyIvarList([self class], &count); for (int i = 0; i < count; i ++) { // 获取属性名字 const char * name = ivar_getName(ivar[i]); NSString * propertyName = [NSString stringWithUTF8String:name]; // 获取属性值 NSString * value = [self valueForKey:propertyName]; [dic setObject:value forKey:propertyName]; } free(ivar); return dic;}
打印结果如下
2016-05-31 17:00:21.781 Runtime[4323:209497] array = { "_IdCard" = 123; "_age" = 12234; "_name" = "\U5f20\U4e09"; "_sex" = 12;}获取属性名和值
- (NSDictionary *)getPropertyListAndValue{ NSMutableDictionary * dic = [NSMutableDictionary dictionary]; unsigned int count = 0; objc_property_t * property = class_copyPropertyList([self class], &count); for (int i = 0; i < count; i ++) { // 获取属性名字 const char * name = property_getName(property[i]); NSString * propertyName = [NSString stringWithUTF8String:name]; // 获取属性值 NSString * value = [self valueForKey:propertyName]; [dic setObject:value forKey:propertyName]; } free(property); return dic;}
2016-05-31 17:04:51.762 Runtime[4357:213684] array = { IdCard = 123; age = 12234; block = blnl; name = "\U5f20\U4e09"; sex = 12;}Swift中获取属性名和属性值
func getAllPropetyAndValue() -> [String: AnyObject] { var count: UInt32 = 0 let ivar = class_copyIvarList(Persion.self, &count) var dic: [String: AnyObject] = Dictionary() for index in 0..<Int(count) { // 获取属性名 let propety = ivar_getName(ivar[index]) let nameString = String.fromCString(propety) // 获取值 let value = self.valueForKey(nameString!) if let value = value { dic[nameString!] = value } } return dic }说明:class_copyPropertyList和property_getName都不能获取对应类父类的属性名,在OC中这两个方法获取的属性名存在一个"_"的差异,在Swift中则不存在
三、获取方法名
- (NSArray *)getMothodName{ NSMutableArray * mothodArray = [NSMutableArray array]; unsigned int count = 0; Method * method = class_copyMethodList([self class], &count); for (int i = 0; i < count; i ++) { // 获取方法名字 SEL methodName = method_getName(method[i]); const char * name = sel_getName(methodName); [mothodArray addObject:[NSString stringWithUTF8String:name]]; } return mothodArray;}四、给OC的类目添加属性、把按钮的Action绑定Block
给OC的类目添加属性:
- (void)setParam:(NSString *)param{ objc_setAssociatedObject(self, @selector(param), param, OBJC_ASSOCIATION_COPY_NONATOMIC);}- (NSString *)param{ return objc_getAssociatedObject(self, _cmd);}Swift中添加属性
private var addressKey: UInt8 = 0extension Persion { var address: String? { get { return objc_getAssociatedObject(self, &addressKey) as? String } set { if let newValue = newValue { objc_setAssociatedObject( self, &addressKey, newValue as NSString?,objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC ) } } }}把按钮的Selector绑定Block:
typedef void(^ButtonBlock)();@interface UIButton (block)- (void)addTarget:(id)target events:(UIControlEvents)event block:(ButtonBlock)block;@end
const void * buttonKey = @"buttonKey";@implementation UIButton (block)- (void)addTarget:(id)target events:(UIControlEvents)event block:(ButtonBlock)block{ objc_setAssociatedObject(self, buttonKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC); [self addTarget:target action:@selector(processButton) forControlEvents:event];}- (void)processButton{ objc_getAssociatedObject(self, buttonKey);}@end调用:
- (void)viewDidLoad{ [self.button addTarget:self events:UIControlEventTouchDown block:^{ NSLog(@"点击事件"); }];}
在swift中绑定:
private var ActionBlockKey: UInt8 = 0typealias ButtonBlock = ((sender: UIButton)-> Void)?class ActionBlockWrapper : NSObject { var block : ButtonBlock init(block: ButtonBlock) { self.block = block }}extension UIButton { func addTarget(controlEvents: UIControlEvents, blick: ButtonBlock) { objc_setAssociatedObject(self, &ActionBlockKey, ActionBlockWrapper.init(block: blick), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) addTarget(self, action: #selector(UIButton.processButton(_:)), forControlEvents: controlEvents) } func processButton(sender: UIButton) { let wrapper = objc_getAssociatedObject(self, &ActionBlockKey) as! ActionBlockWrapper wrapper.block!(sender: sender) }}
四、方法交换
OC中的方法交换:
Method p1 = class_getInstanceMethod([Persion class], @selector(p1));Method p2 = class_getInstanceMethod([Persion class], @selector(p2));method_exchangeImplementations(p1, p2);[p p1];swift中的方法交换:
let p1: Method = class_getInstanceMethod(ViewController.self, #selector(ViewController.mothodFirst))let p2: Method = class_getInstanceMethod(ViewController.self, #selector(ViewController.mothodSecond))method_exchangeImplementations(p1, p2)mothodFirst()
五、解档、归档:当一个对象有很多属性需要进行解/归档的时候,不用一个个属性的去写解/归档操作
这里我定义了一个Persion类来说明
@interface Persion : NSObject@property (copy, nonatomic) NSString * name;@property (assign, nonatomic) int age;@property (copy, nonatomic) NSNumber * height;@end实现:
- (void)encodeWithCoder:(NSCoder *)coder{ unsigned int count = 0; Ivar * ivars = class_copyIvarList([Persion class], &count); for (int i = 0; i < count; i++) { Ivar ivar = ivars[i]; const char * name = ivar_getName(ivar); NSString * strName = [NSString stringWithUTF8String:name]; // kvc 取值 id value = [self valueForKey:strName]; [coder encodeObject:value forKey:strName]; } free(ivars);}- (instancetype)initWithCoder:(NSCoder *)coder{ self = [super init]; if (self) { unsigned int count = 0; // 获取类中所有成员变量名 Ivar * ivars = class_copyIvarList([Persion class], &count); for (int i = 0; i < count; i++) { Ivar ivar = ivars[i]; const char * name = ivar_getName(ivar); NSString * strName = [NSString stringWithUTF8String:name]; // 进行减档 id value = [coder decodeObjectForKey:strName]; // 利用kvc对属性赋值 [self setValue:value forKey:strName]; } free(ivars); } return self;}这样是不是很方便了呢
0 0
- Runtime的简单使用
- Runtime的简单使用
- RunTime的运行机制简单使用
- ios-Runtime的简单使用
- iOS之runtime的简单使用
- java中runtime的简单使用
- iOS简单runtime封装fmdb的使用
- IOS runtime简单使用
- runtime简单使用
- runtime简单使用
- Runtime的简单应用
- runtime的简单介绍
- runtime的简单理解
- runtime 简单的介绍
- Runtime运行时的简单使用,字典转模型
- iOS开发之深入探讨runtime机制02-runtime的简单使用
- Runtime类的使用
- Runtime 类的使用
- secureCRT彩色字体设置
- 连续最大子序列和与最小子序列和
- Middle-题目56:109. Convert Sorted List to Binary Search Tree
- XenServer关键的配置文件
- Jquery 常用函数学习记录
- Runtime的简单使用
- android多分辨率适配
- Android学习笔记之Intent
- Mac OS X 下 TAR.GZ 方式安装 MySQL
- Shell注释
- java jdbc连接数据库(使用mysql进行连接)
- [树形dp][入门]hdu1520 & poj2342 Anniversary party
- Android studio如何使用SVN进行版本控制
- iOS常用技术 - 本地搭建IPv6测试环境