iOS中load方法和分类方法加载和调用顺序
在iOS开发中,我们经常会使用load方法和分类方法来实现一些功能扩展和初始化操作。load方法是在类被加载到内存时自动调用的方法,而分类方法则是为已有的类添加新的方法。本文将详细介绍load方法和分类方法的加载和调用顺序,并通过代码示例来说明。
load方法的加载和调用顺序
在Objective-C中,每个类都有一个load方法,这个方法是在类被加载到内存时自动调用的。load方法的定义如下:
+ (void)load {
// 在这里添加需要执行的代码
}
load方法是在程序运行时自动调用的,由系统负责调用,我们无需手动调用。load方法的调用顺序遵循如下规则:
- 先调用父类的load方法,再调用子类的load方法;
- 先调用类的load方法,再调用分类的load方法;
- 调用顺序是根据类在编译时的顺序来确定的。
下面是一个示例,演示了load方法的加载和调用顺序:
// MyClass.h
@interface MyClass : NSObject
@end
// MyClass.m
#import "MyClass.h"
@implementation MyClass
+ (void)load {
NSLog(@"MyClass load");
}
@end
// MySubClass.h
@interface MySubClass : MyClass
@end
// MySubClass.m
#import "MySubClass.h"
@implementation MySubClass
+ (void)load {
NSLog(@"MySubClass load");
}
@end
上述代码中,MySubClass继承自MyClass,我们可以通过运行下述代码来观察load方法的调用顺序:
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"Before MyClass and MySubClass are loaded");
[MySubClass class];
NSLog(@"After MyClass and MySubClass are loaded");
}
return 0;
}
输出结果如下:
Before MyClass and MySubClass are loaded
MyClass load
MySubClass load
After MyClass and MySubClass are loaded
从输出结果可以看出,首先调用了MyClass的load方法,然后调用了MySubClass的load方法。
分类方法的加载和调用顺序
分类方法是用来为已有的类添加新的方法的。分类方法的定义如下:
@interface ClassName (CategoryName)
// 添加新的方法
@end
分类方法的加载和调用顺序如下:
- 如果有多个分类为同一个类添加了相同的方法,那么只会调用最后编译的分类中的方法;
- 如果有多个分类为同一个类添加了不同的方法,那么每个分类中的方法都会被调用;
- 如果有多个分类为同一个类添加了相同的属性,那么只有最后编译的分类中的属性会生效。
下面是一个示例,演示了分类方法的加载和调用顺序:
// MyClass.h
@interface MyClass : NSObject
@end
// MyClass.m
#import "MyClass.h"
@implementation MyClass
- (void)sayHello {
NSLog(@"Hello from MyClass");
}
@end
// MyClass+Category1.h
@interface MyClass (Category1)
@end
// MyClass+Category1.m
#import "MyClass+Category1.h"
@implementation MyClass (Category1)
- (void)sayHello {
NSLog(@"Hello from Category1");
}
@end
// MyClass+Category2.h
@interface MyClass (Category2)
@end
// MyClass+Category2.m
#import "MyClass+Category2.h"
@implementation MyClass (Category2)
- (void)sayHello {
NSLog(@"Hello from Category2");
}
@end
上述代码中,我们为MyClass类分别添加了Category1和Category2两个分类,它们都重写了sayHello方法。下面是一个使用这些分类的示例:
int main(int argc, char * argv[]) {
@autoreleasepool {
MyClass *myClass = [[MyClass alloc] init];
[myClass sayHello];
}
return 0;
}
输出结果如下:
Hello from Category2
从输出结果可以看出,最后编译的分类Category2中的sayHello方法被调用。如果我们将Category2的内容注释掉,再次运行代码,输出结果为:
Hello from Category1
``