Sian 发表于 2014-3-18 12:21:25

深入浅出谈OC中的类

该示例主要为了说明以下几点:
1、OC中的类其实也是一个对象,这种对象称为类对象,Class类型;
2、通过调用类或对象的class方法可以返回该类的地址,返回数据类型为Class;
3、各类中都存在一个load方法与initialize方法,这两个方法为类方法;
4、load方法在程序加载时即刻被调用,与是否使用该类无关,并且分类中的load方法也会被同时调用;
5、initialize方法则是在该类被使用时调用,并且会将其父类的initialize首先被调用;
6、不使用的类,initialize方法不会被使用;

实现代码参考:

Person.h
//
//Person.h
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
}

@end


Person.m
//
//Person.m
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Person.h"

@implementation Person

// 重写类方法(void)load, 目的在于能够直观地展示该方法被调用;
+ (void)load
{
    NSLog(@"Person_load...");
}

// 重写类方法(void)initialize,原因同上
+ (void)initialize
{
    NSLog(@"Person_initialize...");
}

@end


Student.h
//
//Student.h
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Person.h"

@interface Student : Person

@end


Student.m
//
//Student.m
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Student.h"

@implementation Student

// load方法在程序加载时即被调用,与该类是否有过使用没有关系;
+ (void)load
{
    NSLog(@"Student_load...");
}

// initialize在该类使用时被调用,并用父类的initialize方法也同样会被调用
+ (void)initialize
{
    NSLog(@"Student_initialize...");
}

@end


Boy.h
//
//Boy.h
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Student.h"

@interface Boy : Student

@end


Boy.m
//
//Boy.m
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Boy.h"

@implementation Boy

// 无论父类子类,只要是类,程序执行时该方法即被调用
+ (void)load
{
    NSLog(@"Boy_load...");
}

// 子类可以很好地展示父类相关方法的动作
+ (void)initialize
{
    NSLog(@"Boy_initialize...");
}

@end


Student+load.h//
//Student+load.h
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Student.h"

@interface Student (load)

@end



Student+load.m
//
//Student+load.m
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "Student+load.h"

@implementation Student (load)

// 分类中的load方法在程序加载时也会被被调用,并且与主类中的load方法不冲突,两个load方法同时被调用,这与initialize不一样;
+ (void)load
{
    NSLog(@"Student+load_load...");
}

// 在分类中,initialize方法会替换主类中的该方法,即优先被调用,并且是在该类使用时被调用,与是否使用分类中的方法无关
//+ (void)initialize
//{
//    NSLog(@"Student+load_initialize...");
//}

@end


main.m
//
//main.m
//Class-1
//
//Created by yusian on 14-3-18.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student+load.h"
#import "Person.h"
#import "Student.h"
#import "Boy.h"

// 声明用来说有问题的三个函数,具体函数作用在实现部分有做说明
void classTest();
void loadTest();
void initializeTest();

// 分别调用各功能函数来说明相关问题
int main()
{
   
    classTest();
   
//    loadTest();
   
//    initializeTest();
   
    return 0;
}

// 该方法的作用在于,说明类其实也是一个对象,只不过是一种类类型(Class 类型)的对象
void classTest()
{

    // 创建一个Person对象p,并进行初始化,同时说明p是一个(Person *)类型的数据
    Person * p = [ init];
   
    // 通过对象的class方法可以获取到该类的返回类型及地址,即返回类型为Class,c1为对象p所属类型的地址
    Class c1 = ;
   
    // 通过返回的类型值,再次进行class类方法操作同样返回的是Class类型的地址,得到c2,c2为c1所属类型的地址
    Class c2 = ;
   
    // 通过c1与c2的输出可以看到,c1其实就是c2,即(Person *)的地址,p事实上是对象p的地址
    NSLog(@"p=%p, c1=%p, c2=%p", p, c1, c2);
   
}

// load方法在程序加载时即被调用,所以该不做任何事情也可以得到各类的load方法被调用的输出结果,包含分类中的load方法
void loadTest()
{

}

// initialize方法是在该类第一次使用时调用,并且其父类的initialize也同时被调用,但如果不使用该类,则其initialize方法不被调用,比如说子类中的initialize方法;
void initializeTest()
{
   
//    使用Person对象,则Person类中的initialize方法被调用
//    Person * p = [ init];
//
//    使用Student对象,则Person类与Student类中的initialize方法都会被调用,并且首先调用父类中的initialize方法,子类Boy中的initialize方法则不会被调用
//    Student * s = [ init];
//
//    使用Boy类难以上结论
//    Boy * b = [ init];

}


页: [1]
查看完整版本: 深入浅出谈OC中的类