runtime API的學習

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

相關文章
相關標籤/搜索