Objective-C id类型实现原理
2015-07-31 17:51
519 查看
在 Objective-C中id类型的对象可以转换为任何一种对象,有点类似与void*指针类型的作用。下面简要介绍一下id类型。
id标志符:通用对象类型。id类型是一个独特的数据类型,可以转换为任何数据类型,即id类型的变量可以存放任何数据类型的对象。这是为什么呢?还是从OC的内部实现机制上来分析吧!
在内部处理上,id类型被定义为指向对象的指针,这可以从id的定义中看出。id在objc.h中的定义为:
typedef struct objc_object {
Class isa;
} *id;
而Class为typedef struct objc_class *Class,即Class为struct objc_class的指针别名,而objc_class在runtime.h中的定义为
struct objc_class {
Class isa;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
从上面的代码看出,id是指向objc_object的一个指针。那么它为什么可以指向NSObject对象呢?还是看NSObject的定义吧!
@interface NSObject <NSObject> {
Class isa;
}
可以看出NSObject只有一个Class对象isa,而objc_object也是只有一个Class对象isa,可以看成两者等价(不知道对不对?)。所以id是一个一个比较灵活的对象指针,并且是一个指向任何一个继承了Object(或者NSObject)类的对象。而在cocoa的开发环境里,NSObject是所有类的根类。所以id可以指向任何一个cocoa的合法对象。
从上面的代码分析可以看出,id实际上是一个指向NSObjec对象的实例变量的指针,即id和void*并非完全一样。
PS:id和IMP标志符之间的关系:
id:是一种数据类型;
IMP:指向返回id类型值的方法的指针,而且指向的方法带有self和selector对象作为第一个参数。它是一种C类型,可以认为是一种函数指针。其英文解释:IMP is a C type referring to the implementation of a method, also known as an implementation pointer. It's a pointer to a function returning id, and with self and a method selector (available inside method definitions as the variable _cmd) as the first arguments。
其使用方法为:id (*IMP)(id, SEL, ...);(SEL为选择器selector的一个类型,选择器就是指向方法的一个指针)
对于NSObject对象,你可以这样来获得一个给定方法的IMP:
IMP imp=[obj methodForSelector:@selector(message)];
对于任意的对象object,
IMP imp=[obj methodFor:@selector(message)];
id标志符:通用对象类型。id类型是一个独特的数据类型,可以转换为任何数据类型,即id类型的变量可以存放任何数据类型的对象。这是为什么呢?还是从OC的内部实现机制上来分析吧!
在内部处理上,id类型被定义为指向对象的指针,这可以从id的定义中看出。id在objc.h中的定义为:
typedef struct objc_object {
Class isa;
} *id;
而Class为typedef struct objc_class *Class,即Class为struct objc_class的指针别名,而objc_class在runtime.h中的定义为
struct objc_class {
Class isa;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
从上面的代码看出,id是指向objc_object的一个指针。那么它为什么可以指向NSObject对象呢?还是看NSObject的定义吧!
@interface NSObject <NSObject> {
Class isa;
}
可以看出NSObject只有一个Class对象isa,而objc_object也是只有一个Class对象isa,可以看成两者等价(不知道对不对?)。所以id是一个一个比较灵活的对象指针,并且是一个指向任何一个继承了Object(或者NSObject)类的对象。而在cocoa的开发环境里,NSObject是所有类的根类。所以id可以指向任何一个cocoa的合法对象。
从上面的代码分析可以看出,id实际上是一个指向NSObjec对象的实例变量的指针,即id和void*并非完全一样。
PS:id和IMP标志符之间的关系:
id:是一种数据类型;
IMP:指向返回id类型值的方法的指针,而且指向的方法带有self和selector对象作为第一个参数。它是一种C类型,可以认为是一种函数指针。其英文解释:IMP is a C type referring to the implementation of a method, also known as an implementation pointer. It's a pointer to a function returning id, and with self and a method selector (available inside method definitions as the variable _cmd) as the first arguments。
其使用方法为:id (*IMP)(id, SEL, ...);(SEL为选择器selector的一个类型,选择器就是指向方法的一个指针)
对于NSObject对象,你可以这样来获得一个给定方法的IMP:
IMP imp=[obj methodForSelector:@selector(message)];
对于任意的对象object,
IMP imp=[obj methodFor:@selector(message)];
相关文章推荐
- TMCache: fast object caching for iOS & OS X
- [Object-C]正则表达式 手机号, 邮箱, 车牌号
- [Object-C]使用个推遇到的坑
- Object类
- Flash <object>标签含义解析
- jquery 将 json字符串转成js object
- 0808-080x OBJECT
- Object-C 中的日期(NSDate)
- [Object-c]cocoaPods 安装及遇到问题处理方法
- 黑马程序员--iOS--Objective-C基础 (Foundation框架 一 )
- 编译报错:Undefined symbols for architecture x86_64
- Object-C 中的NSData / NSMutableData
- objective-c 编程的几个调试技巧
- Jackson 高性能的JSON处理 ObjectMapper
- Object-C 四种创建临时字符串的方法
- [Objective-C] NSArray initWithObjects "Expression result unused" warning
- Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect
- Object-C NSDictionary /NSMutableDictionary
- everything is a object2
- Properties vs. instance variables(ios objective-c)