OC类的深入研究
2015-08-19 09:15
453 查看
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编辑如下:
编辑Man.m如下:
为Student新建分类如下:
编辑Student+MJ.h如下:
编辑main.m如下:
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>运行结果如下:
相关文章推荐
- poj2253 最小生成树中的最大边 prim
- LeetCode Binary Tree Preorder Traversal
- HDU 5400 Arithmetic Sequence(2015 Multi-University Training Contest 9 2015多校联合)
- SVM 多分类 -SVM分类opencv3.0源代码
- HDU 1269 -- 迷宫城堡【有向图求SCC的数目 && 模板】
- BZOJ 1695 [Usaco2007 Demo]Walk the Talk 链表+数学
- LeetCode Binary Tree Preorder Traversal
- iOS 网络请求,参数中字典嵌套字典
- UVA - 11346 Probability (概率)
- Chrome清除dns缓存
- Win10 Mobile应用商店更新 大波应用更新下载
- 图结构练习——BFSDFS——判断可达性--------BFS——从起始点到目标点的最短步数
- 算法竞赛入门经典:第八章 高效算法设计 8.8二分查找之范围统计
- 7、串口
- 给大家讲讲在哪些地方发外链最好
- ObjC第六节:OC常用类
- extjs4之合并单元格
- 使用LLDB调试程序
- 导出文件名列表命令
- Java中各种修饰符与访问修饰符的说明