理解 id, Class, isa, SEL, IMP, Method
id 类型
首先介绍两个概念:静态类型和动态类型。
静态类型:将一个指针变量定义为特定类的对象时,使用的是静态类型,在编译的时候就知道这个指针变量所属的类,比如:(下面的p
指针就是静态类型)
NSString *p = [[NSString alloc] init];
动态类型:程序运行时才确定变量的类,比如:(下面的p
指针在编译的时候不知道自己的类型,直到运行时才直到)
id p = [[NSString alloc] init];
id
就是一种动态类型,它可以指向属于任何继承与NSObject
类的对象,这样id
就可以调用项目中所有继承与NSObject
类的方法(但可能调用的方法不在对象中,要小心使用),比如:
@interface Person : NSObject
- (void)speak;
@end
@implementation Person
- (void)speak {
NSLog(@"hello");
}
@end
id p = [[NSString alloc] init];
[p speak]; // 编译可以通过,运行时报错:unrecognized selector sent to instance 0x7fff8b02f288"
id
在内部是如何实现的呢?其实id
是一个结构体指针类型:
typedef struct objc_object *id {
Class isa;
};
可以看出id
内部有一个Class
类型的指针isa
,这里引入了两个新概念:Class
和isa
。
Class 类型和 isa 指针
Class 也是一个结构体指针类型:
typedef struct objc_class *Class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version