id 被称为万能指针,可以指向任何OC对象, 查看id的声明
/// A pointer to an instance of a class.
typedef struct objc_object *id;
id 是由typedef 重新定义的一个 指向结构体 objc_object的指针类型, 注释的解释为: 指向一个类实例的指针
再看下objc_object的定义
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
objc_object 是一个包含 Class类型名为isa成员变量的结构体, 注释解释为: 一个类实现的表现
那么Class又是什么呢, 继续查看Class的定义
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
可以看出Class又是一个指向名为objc_class结构体类型的指针类型别名, 注释解释为: 表现为 Objective-C 类的不透明类型.
也就是说objc_class 中包含了一些隐含意义的数据, 苹果官方并不希望我们对这个结构体了解太多
再看下objc_class的定义
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#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;
objc_class这个结构体, 这个结构体包含了类的一些相关信息
以上数据的关系图如下
//
// Person.h
// id
//
// Created by LiuWei on 15/4/15.
// Copyright (c) 2015年 LiuWei. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)myTest;
@end
//
// Person.m
// id
//
// Created by LiuWei on 15/4/15.
// Copyright (c) 2015年 LiuWei. All rights reserved.
//
#import "Person.h"
@implementation Person
- (void)myTest
{
NSLog(@"我是人类!");
}
@end
<pre name="code" class="html">//
// main.m
// id
//
// Created by LiuWei on 15/4/15.
// Copyright (c) 2015年 LiuWei. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
id per = [Person new];
[per myTest];
Person *p = [Person new];
[p myTest];
return 0;
}
以上代码中 id类型per和生成对象关系图
这时per得到的是[Person new]创建并返回的对象地址, 所有对象中前8字节为isa指针. 这个指针指向含有当前类信息的一个结构体.
所以此时per把对象前8字节看作是拥有一个名为isa成员变量的数据结构objc_class, 然后再从这个结构中读取出 Class类型的数据isa,
再通过这个isa找到当前对象类信息.
Person*类型变量p和对象关系图
指针变量p同上图per作用基本相同, 但p的数据类型为Person*.