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

相关文章
相关标签/搜索