黑马程序员——OC学习之类的本质和常用的继承自NSObject的方法

来源:互联网 发布:哪里有淘宝买家数据 编辑:程序博客网 时间:2024/06/05 17:17

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


本文主要介绍oc中类和对象的区别,以及继承自NSObject的一些常用方法和关键字如selfsuper isa superclass是什么意思等等。

一》先说oc中类和对象的区别

比如有一个Person类的文件如下:

Person.h文件

#import <Foundation/Foundation.h>@interface Person : NSObject@property NSString *name;@end

Person.m文件

#import "Person.h"@implementation Person@end

在main函数中有如下代码;

Person *p1 = [[Person alloc ]init];Person *p2 = [[Person alloc ]init];Person *p2 = [[Person alloc ]init];

那么实际的内存可以表示成这种关系:


其中红色的表示Person类,蓝色的表示Person类的对象

1.     其实红色的Person类也是一种对象,它的类型是Class 类型,可以通过如下方式得到:

Person *p1 = [[Person alloc ]init];

Class p [p1 class];  //注意p前面不带*

多个同一类型的对象通过class方法得到的类名称是相同的,都是Person。

2.     每个Person类的对象中都有一个isa指针指向Person类,因为对象只存储变量,不存储方法,需要通过isa指针来知道访问方法时是那个对象访问的。

3.     其实Person类中还有个superclass指针指向父类,图中未表现出来,Person继承的是NSObject,所以superclass就是指向的NSObject

 

二》继承自NSObject的一些常用方法和关键字

主要介绍一下有关类生命周期的方法如+load+initialize +alloc +new –init –dealloc 还有 self  super  isa superclass 各是什么意思。

1. 先看+load 和 +initialize方法

———Person.h文件

#import <Foundation/Foundation.h>@interface Person : NSObject@end

———Person.m文件

#import "Person.h"@implementation Person//当程序运行时回加载所有的类,类加载完后,不管有没有使用都会调用该方法+ (void)load{    NSLog(@"Person load");}//当类第一次使用时就会调用,只调用一次+ (void)initialize{    NSLog(@"Person initialize");}@end

———在看继承自Person的Student的.h文件

#import <Foundation/Foundation.h>#import "Person.h"@interface Student : Person@end

———Student.m的文件

#import "Student.h"@implementation Student + (void)load{    NSLog(@"Student load");}+ (void)initialize{    NSLog(@"Student initialize");}@end

———main函数中

int main(){return 0;}

的运行结果为:

2014-12-17 16:24:56.831 ocblog5[546:17875] Person load

2014-12-17 16:24:56.832 ocblog5[546:17875] Student load

———修改main函数如下:

int main(){Student *s1 = [[Student alloc ]init];     Student *s2 = [[Student alloc ]init];return 0;}

的运行结果为;

2014-12-17 16:23:19.775 ocblog5[530:17329] Person load

2014-12-17 16:23:19.776 ocblog5[530:17329] Student load

2014-12-17 16:23:19.776 ocblog5[530:17329] Personinitialize

2014-12-17 16:23:19.777 ocblog5[530:17329] Studentinitialize

可以看出如下结论:

1.             不管有没有使用类,当程序启动后,类就会被加载,加载完后就会自己调用+load方法。

2.             只有使用了类的时候才会调用+initialize方法,并且不管使用了多少次都只会调用一次该方法。

3.             +initialize的调用顺序为先调用父类的方法,再调用子类的方法。

 

如果再加入一个分类(category)进来,分类代码如下:

——-Student+JH.h文件

#import "Student.h"@interface Student (JH)@end

———Student+JH.m文件

#import "Student+JH.h"@implementation Student (JH)+ (void)load{    NSLog(@"Student-JH load");}+ (void)initialize{    NSLog(@"Student-JH initialize");}@end

——-main.m文件中

int main(){return 0;}

的运行结果为:

2014-12-17 16:33:50.614 ocblog5[557:19724] Person load

2014-12-17 16:33:50.615 ocblog5[557:19724] Student load

2014-12-17 16:33:50.615 ocblog5[557:19724] Student-JHload

———修改main函数如下:

int main(){     Student *s1 = [[Student alloc ]init];     Student *s2 = [[Student alloc ]init];     return 0;}

的运行结果为;

2014-12-17 16:35:09.098 ocblog5[561:20174] Person load

2014-12-17 16:35:09.099 ocblog5[561:20174] Student load

2014-12-17 16:35:09.099 ocblog5[561:20174] Student-JHload

2014-12-17 16:35:09.099 ocblog5[561:20174] Personinitialize

2014-12-17 16:35:09.099 ocblog5[561:20174] Student-JHinitialize

可以看出如下结论:

a)             分类再程序运行时也会自动加载,并调用+load方法,而且只调用一次。

b)             分类的+initialize方法优先级高于本类,会覆盖本类的方法,但是父类的+initialize方法不受影响,依然会调用。

c)             以上例子没有表现出来,但是要知道的是本类的多个分类都重写了+load和+initialize方法时多个分类的+load方法都会调用,但+initialize方法只会调用最后一个被编译的分类的方法,因为分类的同名方法会被覆盖,也就是随机的。

 

2. 再说+alloc +new –init –dealloc -description方法的作用

首先代码 Person *p = [Personnew];和代码Person *p = [[Personalloc ]init];都是创建一个对象分配空间并初始化。

不同的是 new 就是固定的 alloc + init 的模式,而使用alloc的模式就可以自己选择初始化的构造方法,比较灵活。

-init方法是继承自NSObject对象,也可以自己写构造方法,但一定要记得调用父类的-init方法,形如:

- (id)init{

    if(self = [superinit]){

        //初始化自己类的变量

    }

    return self;

}

这种模式。

-dealloc方法也是继承自NSObject的方法,当对象被销毁时调用,可以用来注销成员变量指向的资源,再没有开启ARC模式的项目中可以使用,使用了ARC模式后编译器不再允许重写了。需要注意的是该函数重写时一定要在最后加上一句[superdealloc];用来释放父类资源。

- (void)dealloc{

        //释放本类资源

    [super dealloc];    //释放父类资源

}                                                                              

-description方法也很好用,作用和java中的toString()方法一样,当直接输出一个类时会调用该方法,可以重写该方法用来输出类的信息。如果没有重写将会输出类的名称和地址。

3. 最后分辨一下 isa superclass  self  super 的作用

isa:是继承自NSObject的成员变量,不可手动访问,作用是让类的对象指向类本身,方便对象调用方法时能辨明是那个对象在使用方法。

superclass:类本身包含这个变量,作用是在类中指向类的父类。

self:可以手动调用的关键字,作用广泛,用来表示当前对象或当前类,有个很有用的例子:[self func] 这么写可以用在类的多态性上让编程更灵活。

super:可以手动调用的关键字,在类中表示调用父类的变量或者方法。



















0 0