Runtime的应用

来自:http://www.imlifengfeng.com/blog/?p=397 1、快速归档

  • (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [self setValue:[aDecoder decodeObjectForKey:key] forKey:key]; } } return self; }

  • (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int outCount; Ivar * ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i ++) { Ivar ivar = ivars[i]; NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)]; [aCoder encodeObject:[self valueForKey:key] forKey:key]; } }

2、Json到Model的转化

  • (instancetype)initWithDict:(NSDictionary *)dict {

    if (self = [self init]) { //(1)获取类的属性及属性对应的类型 NSMutableArray * keys = [NSMutableArray array]; NSMutableArray * attributes = [NSMutableArray array]; /* * 例子 * name = value3 attribute = T@"NSString",C,N,V_value3 * name = value4 attribute = T^i,N,V_value4 */ unsigned int outCount; objc_property_t * properties = class_copyPropertyList([self class], &outCount); for (int i = 0; i < outCount; i ++) { objc_property_t property = properties[i]; //通过property_getName函数获得属性的名字 NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; [keys addObject:propertyName]; //通过property_getAttributes函数可以获得属性的名字和@encode编码 NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; [attributes addObject:propertyAttribute]; } //立即释放properties指向的内存 free(properties);

      //(2)根据类型给属性赋值for (NSString * key in keys) {if ([dict valueForKey:key] == nil) continue;[self setValue:[dict valueForKey:key] forKey:key];}
    复制代码

    } return self; }

3、Category添加属性并生成getter和setter方法 #import <Foundation/Foundation.h>

@interface NSArray (MyCategory) //不会生成添加属性的getter和setter方法,必须我们手动生成 @property (nonatomic, copy) NSString *blog; @end

#import "NSArray+MyCategory.h" #import <objc/runtime.h>

@implementation NSArray (MyCategory)

// 定义关联的key static const char *key = "blog";

/** blog的getter方法 */

  • (NSString *)blog { // 根据关联的key,获取关联的值。 return objc_getAssociatedObject(self, key); }

/** blog的setter方法 */

  • (void)setBlog:(NSString *)blog { // 第一个参数:给哪个对象添加关联 // 第二个参数:关联的key,通过这个key获取 // 第三个参数:关联的value // 第四个参数:关联的策略 objc_setAssociatedObject(self, key, blog, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end

4、Method Swizzling使用 #import "UIViewController+swizzling.h" #import <objc/runtime.h> @implementation UIViewController (swizzling)

  • (void)load { // 通过class_getInstanceMethod()函数从当前对象中的method list获取method结构体,如果是类方法就使用class_getClassMethod()函数获取。 Method fromMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method toMethod = class_getInstanceMethod([self class], @selector(swizzlingViewDidLoad)); /**
    • 我们在这里使用class_addMethod()函数对Method Swizzling做了一层验证,如果self没有实现被交换的方法,会导致失败。
    • 而且self没有交换的方法实现,但是父类有这个方法,这样就会调用父类的方法,结果就不是我们想要的结果了。
    • 所以我们在这里通过class_addMethod()的验证,如果self实现了这个方法,class_addMethod()函数将会返回NO,我们就可以对其进行交换了。 */ if (!class_addMethod([self class], @selector(swizzlingViewDidLoad), method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) { method_exchangeImplementations(fromMethod, toMethod); } }

// 我们自己实现的方法,也就是和self的viewDidLoad方法进行交换的方法。

  • (void)swizzlingViewDidLoad { NSString *str = [NSString stringWithFormat:@"%@", self.class]; // 我们在这里加一个判断,将系统的UIViewController的对象剔除掉 if(![str containsString:@"UI"]){ NSLog(@"统计打点 : %@", self.class); } [self swizzlingViewDidLoad]; } @end

5、Method Swizzling类簇 __NSArrayI才是NSArray真正的类 #import "NSArray+ MyArray.h" #import "objc/runtime.h" @implementation NSArray MyArray)

  • (void)load {//是加载文件到内存执行的方法 跟类的生命周期没有关系 Method fromMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:)); Method toMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(my_objectAtIndex:)); method_exchangeImplementations(fromMethod, toMethod); }
  • (id)my_objectAtIndex:(NSUInteger)index { if (self.count-1 < index) { // 这里做一下异常处理,不然都不知道出错了。 @try { return [self my_objectAtIndex:index]; } @catch (NSException *exception) { // 在崩溃后会打印崩溃信息,方便我们调试。 NSLog(@"---------- %s Crash Because Method %s ----------\n", class_getName(self.class), func); NSLog(@"%@", [exception callStackSymbols]); return nil; } @finally {} } else { return [self my_objectAtIndex:index]; } } @end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 VisualVM 进行性能分析及调优

https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/转载于:https://www.cnblogs.com/adolfmc/p/7238893.html

spring—事务控制

编程式事务控制相关对象 PlatformTransactionManager PlatformTransactionManager 接口是 spring 的事务管理器&#xff0c;它里面提供了我们常用的操作事务的方法。注意&#xff1a; PlatformTransactionManager 是接口类型&#xff0c;不同的 Dao 层技术则有不同的实现类 …

为什么印度盛产码农_印度农产品价格的时间序列分析

为什么印度盛产码农Agriculture is at the center of Indian economy and any major change in the sector leads to a multiplier effect on the entire economy. With around 17% contribution to the Gross Domestic Product (GDP), it provides employment to more than 50…

SAP NetWeaver

SAP的新一代企业级服务架构——NetWeaver    SAP NetWeaver是下一代基于服务的平台&#xff0c;它将作为未来所有SAP应用程序的基础。NetWeaver包含了一个门户框架&#xff0c;商业智能和报表&#xff0c;商业流程管理&#xff08;BPM&#xff09;&#xff0c;自主数据管理&a…

NotifyMyFrontEnd 函数背后的数据缓冲区(一)

async.c的 static void NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) 函数中的主要逻辑是这样的&#xff1a;复制代码if (whereToSendOutput DestRemote) { StringInfoData buf; pq_beginmessage(&buf, A); //cursor 为 A pq…

最后期限 软件工程_如何在软件开发的最后期限内实现和平

最后期限 软件工程D E A D L I N E…最后期限… As a developer, this is one of your biggest nightmares or should I say your enemy? Name it whatever you want.作为开发人员&#xff0c;这是您最大的噩梦之一&#xff0c;还是我应该说您的敌人&#xff1f; 随便命名。 …

SQL Server的复合索引学习【转载】

概要什么是单一索引,什么又是复合索引呢? 何时新建复合索引&#xff0c;复合索引又需要注意些什么呢&#xff1f;本篇文章主要是对网上一些讨论的总结。一.概念单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上。用户可以在多个列上建立索引&#xff0c;这种索…

leetcode 1423. 可获得的最大点数(滑动窗口)

几张卡牌 排成一行&#xff0c;每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动&#xff0c;你可以从行的开头或者末尾拿一张卡牌&#xff0c;最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有卡牌的点数之和。 给你一个整数数组 cardPoi…

pandas处理excel文件和csv文件

一、csv文件 csv以纯文本形式存储表格数据 pd.read_csv(文件名)&#xff0c;可添加参数enginepython,encodinggbk 一般来说&#xff0c;windows系统的默认编码为gbk&#xff0c;可在cmd窗口通过chcp查看活动页代码&#xff0c;936即代表gb2312。 例如我的电脑默认编码时gb2312&…

tukey检测_回到数据分析的未来:Tukey真空度的整洁实现

tukey检测One of John Tukey’s landmark papers, “The Future of Data Analysis”, contains a set of analytical techniques that have gone largely unnoticed, as if they’re hiding in plain sight.John Tukey的标志性论文之一&#xff0c;“ 数据分析的未来 ”&#x…

spring— Spring与Web环境集成

ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的&#xff0c;但是每次从容器中获 得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) &#xff0c;这样的弊端是配置文件加载多次…

Elasticsearch集群知识笔记

Elasticsearch集群知识笔记 Elasticsearch内部提供了一个rest接口用于查看集群内部的健康状况&#xff1a; curl -XGET http://localhost:9200/_cluster/healthresponse结果&#xff1a; {"cluster_name": "format-es","status": "green&qu…

Item 14 In public classes, use accessor methods, not public fields

在public类中使用访问方法&#xff0c;而非公有域 这标题看起来真晦涩。。解释一下就是&#xff0c;如果类变成public的了--->那就使用getter和setter&#xff0c;不要用public成员。 要注意它的前提&#xff0c;如果是private的class&#xff08;内部类..&#xff09;或者p…

子集和与一个整数相等算法_背包问题的一个变体:如何解决Java中的分区相等子集和问题...

子集和与一个整数相等算法by Fabian Terh由Fabian Terh Previously, I wrote about solving the Knapsack Problem (KP) with dynamic programming. You can read about it here.之前&#xff0c;我写过有关使用动态编程解决背包问题(KP)的文章。 你可以在这里阅读 。 Today …

matplotlib图表介绍

Matplotlib 是一个python 的绘图库&#xff0c;主要用于生成2D图表。 常用到的是matplotlib中的pyplot&#xff0c;导入方式import matplotlib.pyplot as plt 一、显示图表的模式 1.plt.show() 该方式每次都需要手动show()才能显示图表&#xff0c;由于pycharm不支持魔法函数&a…

到2025年将保持不变的热门流行技术

重点 (Top highlight)I spent a good amount of time interviewing SMEs, data scientists, business analysts, leads & their customers, programmers, data enthusiasts and experts from various domains across the globe to identify & put together a list that…

spring—SpringMVC的请求和响应

SpringMVC的数据响应-数据响应方式 页面跳转 直接返回字符串 RequestMapping(value {"/qq"},method {RequestMethod.GET},params {"name"})public String method(){System.out.println("controller");return "success";}<bea…

Maven+eclipse快速入门

1.eclipse下载 在无外网情况下&#xff0c;无法通过eclipse自带的help-install new software输入url来获取maven插件&#xff0c;因此可以用集成了maven插件的免安装eclipse(百度一下有很多)。 2.jdk下载以及环境变量配置 JDK是向前兼容的&#xff0c;可在Eclipse上选择编译器版…

源码阅读中的收获

最近在做短视频相关的模块&#xff0c;于是在看 GPUImage 的源码。其实有一定了解的伙伴一定知道 GPUImage 是通过 addTarget 链条的形式添加每一个环节。在对于这样的设计赞叹之余&#xff0c;想到了实际开发场景下可以用到的场景&#xff0c;借此分享。 我们的项目中应该有很…

马尔科夫链蒙特卡洛_蒙特卡洛·马可夫链

马尔科夫链蒙特卡洛A Monte Carlo Markov Chain (MCMC) is a model describing a sequence of possible events where the probability of each event depends only on the state attained in the previous event. MCMC have a wide array of applications, the most common of…