一、使用介绍
项目有的时候,会遇到一些特殊的处理,想要根据一个实例的引用,获取这个实例在代码中的名称。比如在处理View的坐标的时候,我们将UIView的坐标信息配置到plist文件中,我们可以设置一个key,再通过这个key来获取配置文件中的坐标等信息。有没有更简单的方法呢,或者我只想简单的用实例变量的变量名做为key。下面就介绍一种简单的,根据实例变量的引用获取实例变量名的办法。
转载请保留原本链接:http://my.oschina.net/taptale/blog/110626
二、引用文件
第一步,我们需要引入我们需要的头文件,在需要使用的类中引用下面代码
1
|
#import <objc/runtime.h> |
三、运行原理
我们可以从苹果官方的开发文档中查看到详细的运行时的使用方法及API,官方并没有直接提供根据实例的引用获取实例变量名称的办法,所以我们需要自己去实现。
在官方的API中我们可以找到以下几个方法
(1)Describes the instance variables declared by a class.
Ivar * class_copyIvarList(Class cls, unsigned int *outCount)
(2) Reads the value of an instance variable in an object.
id object_getIvar(id object, Ivar ivar)
(3) Returns the name of an instance variable.
const char * ivar_getName(Ivar ivar)
- 根据(2)中的API,我们可以获取到当前迭代中的Ivar对应的实例变量的引用
- 将获取到的实例变量与传递过来的实例变量的地址比较
- 如果地址相同,说明当前的Ivar为传递过来实例变量的Ivar,可以通过(3)获取变量的名称并返回
四、代码
(1)根据上面的原理我们可以得到第一版本的代码,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
- (NSString *)nameWithInstance:(id)instance { unsigned int numIvars = 0;
NSString *key=nil;
Ivar * ivars = class_copyIvarList([self.target class ], &numIvars);
for ( int i = 0; i < numIvars; i++) {
Ivar thisIvar = ivars[i];
if ((object_getIvar(self.target, thisIvar) == instance)) {
key = [NSString stringWithUTF8String:ivar_getName(thisIvar)];
break ;
}
}
free (ivars);
return key;
} |
(2)在测试中发现到达上面的if语句的时候,程序有的时候就会crash,经详细测试发现,每次迭代到非objective-c对象的时候,如基本数据类型,BOOL、int、float就会报错。
原因出在object_getIvar这个方法中,当遇到非objective-c对象时,并直接crash,后来查看官方解释
The value of the instance variable specified by ivar, or nil if object is nil.
并没有明确的给出遇到非对象时会crash,也并不会返回nil
我们需要进行一下修正,当遇到非objective-c的时候,需要跳过执行。最终代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
- (NSString *)nameWithInstance:(id)instance { unsigned int numIvars = 0;
NSString *key=nil;
Ivar * ivars = class_copyIvarList([self.target class ], &numIvars);
for ( int i = 0; i < numIvars; i++) {
Ivar thisIvar = ivars[i];
const char *type = ivar_getTypeEncoding(thisIvar);
NSString *stringType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
if (![stringType hasPrefix:@ "@" ]) {
continue ;
}
if ((object_getIvar(self.target, thisIvar) == instance)) {
key = [NSString stringWithUTF8String:ivar_getName(thisIvar)];
break ;
}
}
free (ivars);
return key;
} |
相关推荐
iOS网络高级编程 iPhone和iPad的企业应用开发 [(美)考克斯PDF电子书下载 带书签目录 高清完整版
Apple苹果IOS开发Swift编程语言入门教程中文版.pdf
iOS网络高级编程 iPhone和iPad的企业应用开发--高清版.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
文件太大,我上传到百度云里了,下载连接即可,IOS进阶从初级到高级教程
从入门篇到高级篇,以swift为主干,1个app实战项目为线索,从单元格定制化,导航控制转场,堆叠视图,等基础知识到详情页增强,导航条美化,基础动画,可视化特效等细节知识点入手,由浅入深到最后的高级教程,仅供...
第8 章 实战2:WhatsApp消息拦截 180 8.1 WhatsApp 简介 180 8.2 分析源代码结构,并定位监听点 180 8.2.1 class-dump 获取.h 文件 180 8.2.2 导入Xcode 182 8.2.3 找到WhatsAppAppDelegate 182 8.2.4 ...
iOS开发试题大全:笔试面试一千题,包含1000道iOS试题和参考答案,题型包含:判断题、单选题,多选题和面试题。分为这套资料共分为"语法","常识","界面","iOS","操作","数据结构","多线程","网络","多媒体","安全"十...
block,局部变量,全部变量,static的静态变量关系
资源名称:iOS开发视频教程资源目录:【】iOS开发视频教程-第01讲-iOS历史介绍【】iOS开发视频教程-第02讲-XCode安装【】iOS开发视频教程-第03讲-UIView_PPT【】iOS开发视频教程-第04讲-UILabel【】iOS开发视频教程-...
ios 中的全局变量 可以在 各个类之间 对变量进行使用 不拘泥
iOS核心动画高级技巧iOS核心动画高级技巧iOS核心动画高级技巧iOS核心动画高级技巧iOS核心动画高级技巧
Intermediate iOS Programming with Swift: iOS 10 and Swift 3 by Simon Ng English | 21 Jun. 2017 | ASIN: B0733C5K1D | 790 Pages | AZW3 | 37.88 MB Learn by Doing It's not just about the theory or syntax...
iOS动画的高级教程英文版,pdf版本。 此外我还上传了英文版,只需要3积分。
IOS 传值 变量 利用临时变量在两个ViewController之间传值
iOS Core Animation: Advanced Techniques的中文翻译版本
资源名称:iOS开发系列视频教程:Objective-C 资源目录: 【】无限互联iOS开发视频教程-Objective-C部分(第一部分) 【】无限互联iOS开发视频教程-Objective-C部分(第七部分) 【】无限...
ios微博项目视频教程:ios项目开发流程
iOS开发教程:Storyboard全解析-第一部分
小白的Python入门教程实战篇:网站+iOS App源码 小白的Python入门教程实战篇:网站+iOS App源码 小白的Python入门教程实战篇:网站+iOS App源码 小白的Python入门教程实战篇:网站+iOS App源码 小白的Python入门教程...
如果你是一名有经验的开发者并对开发以数据为中心的iPhone和iPad应用程序感兴趣,那么《移动开发经典丛书:iOS数据库应用高级编程(第2版)》恰好适合你。这本必须拥有的书进行了新的充分修订,并且在结构上对应企业...