iOS class深入理解: 实例对象、类对象、元类和isa指针

来源:互联网 发布:java web mail 编辑:程序博客网 时间:2024/05/17 05:55

你要知道的class都在这里
转载请注明出处http://blog.csdn.net/u014205968/

深入代码理解instance、class object、metaclass
面向对象编程中,最重要的概念就是类,下面我们就从代码入手,看看OC是如何实现类的。

instance 对象实例
我们经常使用id来声明一个对象,那id的本质又是什么呢?打开#import

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;
/* Use Class instead of struct objc_class * */
struct objc_classs结构体里存放的数据称为元数据(metadata),通过成员变量的名称我们可以猜测里面存放有指向父类的指针、类的名字、版本、实例大小、实例变量列表、方法列表、缓存、遵守的协议列表等,这些信息就足够创建一个实例了,该结构体的第一个成员变量也是isa指针,这就说明了Class本身其实也是一个对象,我们称之为类对象,类对象在编译期产生用于创建实例对象,是单例,因此前文中的栗子其实应该表达为str的isa指针指向了NSString类对象那么这个结构体的isa指针又指向什么呢?

类对象中的元数据存储的都是如何创建一个实例的相关信息,那么类对象和类方法应该从哪里创建呢?就是从isa指针指向的结构体创建,类对象的isa指针指向的我们称之为元类(metaclass),元类中保存了创建类对象以及类方法所需的所有信息,因此整个结构应该如下图所示:

iOS class深入理解: 实例对象、类对象、元类和isa指针

通过上图我们可以清晰的看出来一个实例对象也就是struct objc_object结构体它的isa指针指向类对象,类对象的isa指针指向了元类,super_class指针指向了父类的类对象,而元类的super_class指针指向了父类的元类,那元类的isa指针又指向了什么?为了更清晰的表达直接使用一个大神画的图。

iOS class深入理解: 实例对象、类对象、元类和isa指针

通过上图我们可以看出整个体系构成了一个自闭环,如果是从NSObject中继承而来的上图中的Root class就是NSObject。至此,整个实例、类对象、元类的概念也就讲清了,接下来我们在代码中看看这些概念该怎么应用。

类对象
有如下代码

@interface Person : NSObject

@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) NSUInteger age;

@end

@implementation Person

@synthesize name = _name;
@synthesize age = _age;

@end

int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
Class c1 = [p class];
Class c2 = [Person class];
//输出 1
NSLog(@”%d”, c1 == c2);
}
return 0;
}
c1是通过一个实例对象获取的Class,实例对象可以获取到其类对象,类名作为消息的接受者时代表的是类对象,因此类对象获取Class得到的是其本身,同时也印证了类对象是一个单例的想法。
那么如果我们想获取isa指针的指向对象呢?

介绍两个函数

OBJC_EXPORT BOOL class_isMetaClass(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

OBJC_EXPORT Class object_getClass(id obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_isMetaClass用于判断Class对象是否为元类,object_getClass用于获取对象的isa指针指向的对象。

再看如下代码:

int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
//输出1
NSLog(@”%d”, [p class] == object_getClass(p));
//输出0
NSLog(@”%d”, class_isMetaClass(object_getClass(p)));
//输出1
NSLog(@”%d”, class_isMetaClass(object_getClass([Person class])));
//输出0
NSLog(@”%d”, object_getClass(p) == object_getClass([Person class]));
}
return 0;
}
通过代码可以看出,一个实例对象通过class方法获取的Class就是它的isa指针指向的类对象,而类对象不是元类,类对象的isa指针指向的对象是元类。

备注
由于作者水平有限,难免出现纰漏,如有问题还请不吝赐教。

以上就是iOS class深入理解: 实例对象、类对象、元类和isa指针的全文介绍,希望对您学习和使用ios应用开发有所帮助.

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 钢板平整机 耕整机 亩平方丈 1亩等于多少平方丈 1平方丈等于多少平方米 平方丈等于多少平方米 平方丈 尺等于多少平方 平方尺等于多少平方米 平方尺 平方尺等于 100尺等于多少平方 一平方尺 一千尺等于多少平方 香港房子一尺多少平方 一平方多少尺 一尺多少平方 300尺等于多少平方 1平方等于多少尺 1平方尺等于多少平方米 平方尺换算 500尺等于多少平方 平方尺怎么算 1000尺是多少平方 100平方尺等于多少平方米 一平方尺是多大 600尺等于多少平方 香港1000尺是多少平方 三千尺是多少平方 香港平方尺等于多少平方米 苏士澍一平方尺多少钱 一平方等于几尺 三千尺等于多少平方 香港600尺是几平方 1亩等于多少平方尺 400尺等于多少平方 八百尺等于多少平方 香港房子 香港房子1000尺是中国多少平方 香港房子1200尺是中国多少平方 平方米等于多少平方尺