动态建立一个类html
//TODO:ios
参照objc runtime的文章写一个demo,而后把vc中的代码和运行结果贴出来app
- (void)viewDidLoad { [super viewDidLoad]; //利用RunTime建立一个类 Class PersonClass = objc_allocateClassPair([NSObject class], "Person", 0); class_addIvar(PersonClass, "avatar", sizeof(UIImage *), log2(sizeof(UIImage *)), @encode(UIImage *)); class_addIvar(PersonClass, "name", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *)); objc_registerClassPair(PersonClass); unsigned int count = 0; Ivar *members = class_copyIvarList(PersonClass, &count); for (int i = 0 ; i < count; i++) { Ivar var = members[i]; const char *memberName = ivar_getName(var); const char *memberType = ivar_getTypeEncoding(var); NSLog(@"memberType %s: memberName %s",memberType,memberName); } Ivar nameIvar = class_getInstanceVariable(PersonClass, "name"); Ivar avatarIvar = class_getInstanceVariable(PersonClass, "avatar"); id personObject = [[NSClassFromString(@"Person") alloc]init]; UIImage *avartarImage = [UIImage imageNamed:@"IMG_1.JPG"]; NSLog(@"avartarImage == %@",avartarImage); object_setIvar(personObject, nameIvar, @"张三"); object_setIvar(personObject, avatarIvar,avartarImage ); NSString *achivedName = object_getIvar(personObject, nameIvar); UIImage *achivedAvartarImage = object_getIvar(personObject, avatarIvar); NSLog(@"runtime achivedAvartarImage == %@",achivedAvartarImage); NSLog(@"runtime achivedName == %@",achivedName); NSLog(@"try kvc instead "); [personObject setValue:@"李四" forKey:@"name"]; [personObject setValue:avartarImage forKey:@"avatar"]; NSLog(@"kvc name == %@",[personObject valueForKey:@"name"]); NSLog(@"kvc image == %@",[personObject valueForKey:@"avatar"]); // Do any additional setup after loading the view, typically from a nib. }
打印结果ui
memberType @: memberName avataratom
memberType @: memberName nameurl
avartarImage == <UIImage: 0x135e3d0f0>, {2448, 3264}.net
runtime achivedAvartarImage == <UIImage: 0x135e3d0f0>, {2448, 3264}3d
runtime achivedName == 张三指针
try kvc instead code
kvc name == 李四
kvc image == <UIImage: 0x135e3d0f0>, {2448, 3264}
runtime过程当中出现了内存管理的问题,野指针。相反的KVC就不会遇到这样的问题
1,常见的几种用法找一下,MJRefresh和MJExtension中
2,修改系统经常使用的方法
3,建立匿名对象
4,JSPatch了解一下
5,发布app
修改系统API方法的实现
- (void)backup{ Class dynaClass = objc_allocateClassPair([NSObject class], "HXShareItem", 0); class_addIvar(dynaClass, "hxImage", sizeof(UIImage *), log2(sizeof(UIImage *)), @encode(UIImage *)); class_addIvar(dynaClass, "hxImagePath", sizeof(NSURL *), log2(sizeof(NSURL *)), @encode(NSURL *)); class_addMethod(dynaClass, @selector(activityViewControllerPlaceholderItem:), (IMP)activityViewControllerPlaceholderItem, "@@:@"); class_addMethod(dynaClass, @selector(activityViewController:itemForActivityType:), (IMP)activityViewControlleritemForActivityType, "@@:@@"); //声明类遵照UIActivityItemSource 协议 class_addProtocol(dynaClass, @protocol(UIActivityItemSource)); objc_registerClassPair(dynaClass); Ivar imageIvar = class_getInstanceVariable(dynaClass, "hxImage"); Ivar pathIvar = class_getInstanceVariable(dynaClass, "hxImagePath"); int count = 0; Ivar *members = class_copyIvarList([dynaClass class], &count); for (int i = 0 ; i < count; i++) { Ivar var = members[i]; const char *memberName = ivar_getName(var); const char *memberType = ivar_getTypeEncoding(var); NSLog(@"memberType %s: memberName %s",memberType,memberName); } id dynaObject = [[NSClassFromString(@"HXShareItem") alloc]init]; object_setIvar(dynaObject, imageIvar, [UIImage imageNamed:@"IMG_1.JPG"]); UIImage *image2 = object_getIvar(dynaObject, imageIvar); NSLog(@"image2 == %@ class %@",image2,dynaClass); object_setIvar(dynaObject, pathIvar, [NSURL URLWithString:@"http://www.baidu.com"]); // [NSURL URLWithString:@"http://img5.duitang.com/uploads/item/201601/20/20160120132111_LGiVZ.thumb.224_0.jpeg"] NSURL *url = object_getIvar(dynaObject, pathIvar); NSLog(@"url1 == %@",url); }
采用了KVC对其中的内容进行赋值
#pragma mark - 用OC动态实现一个类 //定义协议方法1 返回图片 id activityViewControllerPlaceholderItem(id self,SEL _cmd,UIActivityViewController *activityViewController){ UIImage *image = [self valueForKey:@"hxImage"]; NSLog(@"image == %@",image); return image; } //定义协议方法2 返回网址 id activityViewControlleritemForActivityType(id self,SEL _cmd,UIActivityViewController *activityViewController,NSString *activityType){ NSURL *url = [self valueForKey:@"hxImagePath"]; NSLog(@"url == %@",url); return url; } //调用动态类的过程 -(void)startFromALAssets{ NSMutableArray *shareItems = [NSMutableArray array]; Class HXShareItemClass =NSClassFromString(@"HXShareItem"); if (!HXShareItemClass) { //动态生成一个类 HXShareItemClass = objc_allocateClassPair([NSObject class], "HXShareItem", 0); class_addIvar(HXShareItemClass, "hxImage", sizeof(UIImage *), log2(sizeof(UIImage *)), @encode(UIImage *)); class_addIvar(HXShareItemClass, "hxImagePath", sizeof(NSURL *), log2(sizeof(NSURL *)), @encode(NSURL *)); //实现协议的必须方法 class_addMethod(HXShareItemClass, @selector(activityViewControllerPlaceholderItem:), (IMP)activityViewControllerPlaceholderItem, "@@:@"); class_addMethod(HXShareItemClass, @selector(activityViewController:itemForActivityType:), (IMP)activityViewControlleritemForActivityType, "@@:@@"); //声明类遵照UIActivityItemSource 协议 class_addProtocol(HXShareItemClass, @protocol(UIActivityItemSource)); objc_registerClassPair(HXShareItemClass); } // 网址和placeholder是独立的,具体做用要后续看看。placeholder的字面意思是占位 id dynaObject = [[NSClassFromString(@"HXShareItem") alloc]init]; //采用KVC的方式是能够的 [dynaObject setValue:[UIImage imageNamed:@"IMG_1.JPG"] forKey:@"hxImage"]; [dynaObject setValue:[NSURL URLWithString:@"http://img5.duitang.com/uploads/item/201601/20/20160120132111_LGiVZ.thumb.224_0.jpeg"] forKey:@"hxImagePath"]; if (dynaObject) { [shareItems addObject:dynaObject]; } //调用分享的组件 UIActivityViewController *activityVC =[[UIActivityViewController alloc]initWithActivityItems:shareItems applicationActivities:nil]; if (activityVC) { [self presentViewController:activityVC animated:YES completion:nil]; } }
http://blog.csdn.net/u013538542/article/details/50923701
http://www.cocoachina.com/ios/20151231/14828.html
http://www.cocoachina.com/ios/20160128/15154.html
http://www.cocoachina.com/ios/20160324/15768.html
http://www.cocoachina.com/ios/20160523/16386.html
http://www.360doc.com/content/11/1231/10/8455184_176246899.shtml
拦截系统方法的一次实践
处理按钮不能被连续点击的问题。
经过hzt_ignoreEvent 设定值,使按钮在指定时间hzt_acceptEventInterval内不能够连续被点击
#import <UIKit/UIKit.h> @interface UIButton (HZTButton) @property (nonatomic, assign) NSTimeInterval hzt_acceptEventInterval; @end
#import "UIButton+HZTButton.h" @interface UIButton () @property (nonatomic,assign) BOOL hzt_ignoreEvent; @end @implementation UIButton (HZTButton) static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval"; static const char *UIControl_ignoreEvent = "UIControl_ignoreEvent"; + (void)load { Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:)); Method b = class_getInstanceMethod(self, @selector(__hzt_sendAction:to:forEvent:)); method_exchangeImplementations(a, b); } - (void)__hzt_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { if (self.hzt_ignoreEvent){ NSLog(@"not send"); self.enabled = NO; return; } if (self.hzt_acceptEventInterval > 0) { self.hzt_ignoreEvent = YES; [self performSelector:@selector(setHzt_ignoreEvent:) withObject:@(NO) afterDelay:self.hzt_acceptEventInterval]; } [self __hzt_sendAction:action to:target forEvent:event]; } - (BOOL)hzt_ignoreEvent{ BOOL ignore = [objc_getAssociatedObject(self,UIControl_ignoreEvent) boolValue]; return ignore; } - (void)setHzt_ignoreEvent:(BOOL)hzt_ignoreEvent{ self.enabled = !hzt_ignoreEvent; objc_setAssociatedObject(self, UIControl_ignoreEvent, @(hzt_ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSTimeInterval)hzt_acceptEventInterval { double timeInterval = [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue]; if (timeInterval==0) { timeInterval = 3; } return timeInterval; } - (void)setHzt_acceptEventInterval:(NSTimeInterval)hzt_acceptEventInterval { objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(hzt_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end
http://www.cocoachina.com/ios/20150828/13260.html