文档章节

runtime API的学习

云飞扬v5
 云飞扬v5
发布于 2016/11/02 20:09
字数 995
阅读 4
收藏 0

动态创建一个类

 

 

//TODO:

参照objc runtime的文章写一个demo,然后把vc中的代码和运行结果贴出来

 

- (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.
}

 

打印结果

  memberType @: memberName avatar

  memberType @: memberName name

  avartarImage == <UIImage: 0x135e3d0f0>, {2448, 3264}

  runtime achivedAvartarImage == <UIImage: 0x135e3d0f0>, {2448, 3264}

  runtime achivedName == 张三

   try kvc instead 

 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

© 著作权归作者所有

云飞扬v5
粉丝 14
博文 105
码字总数 67465
作品 0
金华
私信 提问
runtime 运行时机制 完全解读

我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助! 首先,第一个问题,1》runtime实现的机制是什么,怎么用,一般用于干嘛?这个问...

哥特复心
2014/08/06
82.2K
10
swoole| swoole 协程知识点小结

date: 2019-04-30 23:11:23 title: swoole| swoole 协程知识点小结 本文要点: swoole 协程现状一览: 学不动? 其实是更简单了 使用 swoole 协程很简单: 开个协程, 协程里写非阻塞代码 展望 sw...

daydaygo
05/02
0
0
快速了解 Deno 目前的 API

Deno 是 Node.js 之父新造的轮子。旨在用 Golang 和 TypeScript 实现一个很小的 JS runtime。(其目标不是取代 Node.js) 由于 Deno 还没有发布可直接运行的二进制文件,所以想要了解 Deno 的...

方应杭在饥人谷
2018/06/01
0
0
每日科技英文47: 微软的多线程,多任务力作Napa.js库

今日要点: 微软napa.js让google v8 js引擎具有多线程多任务运行功能 nodejs基于v8引擎,因此napa.js也可以适配到nodejs上 napa.js核心代码都是使用c++11标准撰写,代码精心设计,编写优美,代...

随风而行之青衫磊落险峰行
2017/12/17
0
0
General APIs mapping (通用 API mapping)

1、Android到Windows的API mappings 对于Android开发者,同样可以在API mapping 索引中找到映射,与使用iOS映射的方式一样。 我们提供了一个 API 映射索引来帮助你找到与 Windows 运行时 AP...

失足处男的倒霉孩子
2013/12/25
244
0

没有更多内容

加载失败,请刷新页面

加载更多

Giraph源码分析(八)—— 统计每个SuperStep中参与计算的顶点数目

作者|白松 目的:科研中,需要分析在每次迭代过程中参与计算的顶点数目,来进一步优化系统。比如,在SSSP的compute()方法最后一行,都会把当前顶点voteToHalt,即变为InActive状态。所以每次...

数澜科技
今天
4
0
Xss过滤器(Java)

问题 最近旧的系统,遇到Xss安全问题。这个系统采用用的是spring mvc的maven工程。 解决 maven依赖配置 <properties><easapi.version>2.2.0.0</easapi.version></properties><dependenci......

亚林瓜子
今天
10
0
Navicat 快捷键

操作 结果 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的sql语句 F6 打开一个mysql命令行窗口 ctrl+l 删除一行 ...

低至一折起
今天
9
0
Set 和 Map

Set 1:基本概念 类数组对象, 内部元素唯一 let set = new Set([1, 2, 3, 2, 1]); console.log(set); // Set(3){ 1, 2, 3 } [...set]; // [1, 2, 3] 接收数组或迭代器对象 ...

凌兮洛
今天
4
0
PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部