深入浅出谈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]