動態建立一個類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