本文主要是介绍OC类的深入研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、类在创建对象之前也需要加载进空间,也需要占据内存。2、类只会被加载一次。类也是一个对象,但它的类型是Class类型,就是说类本身也是一个对象,是个Class类型的对象,简称类对象。例如新建一个Person类的对象Person *p=[[Person alloc] init];那么p就是Person类型,而Person是个Class类型的类对象。但平时所说的类就是类对象。
3、由以上得知,创建一个对象的过程是:先由Class类创建出一个类对象,再由类对象创建出一个具体的对象。例如创建一个Person对象时先由Class创建Person类对象,再利用Person类对象创建出Person类型的对象。
4、获取内存中类对象(即对象中isa指针的方法):[对象名 class];
利用对象直接调用从根类继承而来的class对象方法即可返回Class类型的数据。注意:类对象是Class类型的数据,Class类型是指针类型,所以在声明Class类型的类对象时不能再加“*”,因为是个地址,所以在打印时用%p打印地址。
5.获取类对象的几种方法:
(一)、在外部获取
(1)Class c=[对象名 class] ;或Class c=对象名.class;
(2)Class c=[类名 class];或Class c=类名.class;
(二)、在成员方法内获取
无论是在对象方法还是类方法中都可以用以下方式获取(值都一样):
Classc=[self class];或Class c=self.class;
6、获取的类对象的作用:
类名就代表类对象,用类名可以直接调用类方法还可以创建对象。利用类对象同样也可以直接调用类方法,也可以创建对象。
就是说:类对象==类 类对象和类具有同样的功能。类对象的由来:
一个类在内存中只有一个存储空间,我们称这个存储空间为类对象。之所以称为类_对象,是因为它也是由Class这个类创建出来的。
7、类的加载过程:
先加载父类,再加载子类。当程序一启动的时候就会把所有的类都加载了一遍。验证类是否被加载的方法:每个类被加载完时都会调用根类的类方法+(void)load;注意:因为每个类都会被加载一次,仅仅一次,所以每一个类的load类方法都会被执行一次(仅仅一次)。验证时只需要在实现中重写根类的类方法+(void)load即可。
切记:只要程序一启动就会把所有的类给加载一遍,切记是所有的类,不管用到还是没有用到只要在同一个程序都会被加载一遍。
8、监听类的加载过程:
(1)在类被加载的时候调用:+(void)load;这个根类的类方法
(2)在类被加载完毕时再调用:+(void)initialize;这个类方法。
注意:对于+(void)load;这个类方法——>当程序启动的时候就会加载一次项目中所有的类。类加载完毕时就会调用+load方法。
而对于+(void)initialize;这个用于初始化操作的类方法——>当第一次使用这个类的时候,就会被调用一次(仅仅一次),如果从未使用就不会被加载,此处的初始化是指类的初始化。
(3)当所有类加载完毕,使用某个类时会先调用这个类的父类initialize方法初始化这个类从父类继承来的成员,然后再调用自身的initialize方法初始化自己扩展的成员。
(4)分类也会被加载。注意:可以在分类中重写load方法覆盖,但不会覆盖原先类(分类为谁而写的,谁就是原先类)的load方法。分类的load方法最后会被加载。分类中也可以重写initialize类方法进行监听。当所有类和分类都被加载完成时,使用某个类时,如果使用的这个类没有分类或分类中没有重写+initialize方法就会调用这个类的initialize类方法,如果使用的这个类有分类且分类中重写了+initialize方法,就会调用分类的initialize方法而绝对不会再调用父类的initialize类方法,这是因为分类的优先级大于原先类的优先级,用原先类调用任何方法时也与此类似,先从分类找,找不到就依次从原先类、父类中寻找。
9、总结:
(1)当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。
(2)当第一次使用某个类时,就会使用当前类的+initialize方法(如果有分类且分类中也重写了+initialize方法的情况下只会调用分类的+initialize方法);
(3)加载时,先加载父类再加载子类(先调用父类的+load方法,再调用子类的+load方法)。初始化的时候,会先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)。
10、如果想在类的第一次初始化的时候做一些事情,就要为它重写+initialize方法。
代码验证,实例如下:
新建Man.h编辑如下:
<span style="font-size:14px;">//
// Man.h
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>@interface Man : NSObject@end
</span>
编辑Man.m如下:
<span style="font-size:14px;">//
// Man.m
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Man.h"@implementation Man
-(id)init{if(self=[super init]){NSLog(@"Man-------—init调用");}return self;
}
+(void)load{NSLog(@"Man-------+load调用");
}
+(void)initialize{NSLog(@"Man-------+initialize调用");
}
@end
</span>
新建Person.h编辑如下:
<span style="font-size:14px;">//
// Person.h
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Man.h"@interface Person : Man
@end
</span>
编辑Person.m如下:
<span style="font-size:14px;">//
// Person.m
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Person.h"@implementation Person
-(id)init{if(self=[super init]){NSLog(@"Person-------—init调用");}return self;
}
+(void)load{NSLog(@"Person-------+load调用");
}
+(void)initialize{NSLog(@"Person-------+initialize调用");
}
@end
</span>
新建Student.h如下:
<span style="font-size:14px;">//
// Student.h
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Person.h"@interface Student : Person@end
</span>
编辑Student.m如下:
<span style="font-size:14px;">//
// Student.m
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Student.h"@implementation Student
-(id)init{if(self=[super init]){NSLog(@"Student-------—init调用");}return self;
}
+(void)load{NSLog(@"Student-------+load调用");
}
+(void)initialize{NSLog(@"Student-------+initialize调用");
}
@end
</span>
为Student新建分类如下:
编辑Student+MJ.h如下:
//
// Student+MJ.h
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Student.h"@interface Student (MJ)@end
编辑
Student+MJ.m如下:
//
// Student+MJ.m
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import "Student+MJ.h"@implementation Student (MJ)
+(void)load{NSLog(@"Man分类MJ-------+load调用");//load方法不会覆盖,会将分类、原来类、父类都会一一加载
}
+(void)initialize{NSLog(@"Man分类MJ-------+initialize调用");//在使用原先类或原先类的子类时,子类和所在的原来类只会被加载一方的initialize方法,因为分类优先级大于原先类,所以只会执行分类的initialize方法。
}
@end
编辑main.m如下:
<span style="font-size:14px;">//
// main.m
// 类的深入研究
//
// Created by apple on 15/8/19.
// Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[])
{@autoreleasepool {[[Student alloc] init];[[Man alloc] init];}return 0;
}
</span>
运行结果如下:
这篇关于OC类的深入研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!