RunTime在項目中使用較少,但需要時運用確能事半功倍。項目中對其進行了封裝,這里只簡單碼一下簡單的應用。
兩道試題起
- 第一題
@implementation Son : Father
-(id)init{
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
打印結果都是Son.
self 是類的隱藏參數,指向當前調用方法的這個類的實例。
super 本質是一個編譯器標示符,和 self 是指向的同一個消息接受者。
不同的是,super告訴編譯者從父類類調用方法,如果父類沒有,只能去NSObject中。
NSObject 這個類調用的class 方法時,返回的都是son.
- 第二道題
@interface Sark : NSObject
@end
@implementation Sark
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
NSLog(@"%d %d %d %d", res1, res2, res3, res4);
}
return 0;
}
打印結果:1,0,0,0;
類目中可以擴展方法,但由于類目并不是一個類,不能擴展屬性。如果定義屬性則不生成相應的實例變量(實例變量是由類定義的變量),沒有實現相應的setter 和 getter 方法。即使實現了setter和getter方法也無法保存數據。但可以通過runTime屬性關聯,變通添加屬性。
屬性關聯
@interface UIViewController (Category)
@property (nonatomic,strong) NSString *name;
@end
*********數據實質的存儲位置*********
static char nameKey ;
//static const char *key = "name";
-(void)setName:(NSString *)name{
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)name{
return objc_getAssociatedObject(self, &nameKey);
}
需要給某個類添加方法時,可重寫父類方法,也可以runtime交換方法。但重寫會覆蓋父類方法,且不能調用super.
方法交換
implementation UIImage (Image)
// 加載分類到內存的時候調用
// 一般方法交換會寫在這個方法中
+(void)load{
// 獲取imageWithName方法地址
Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));
// 獲取imageWithName方法地址
Method imageName = class_getClassMethod(self, @selector(imageNamed:));
// 交換方法地址,相當于交換實現方式
method_exchangeImplementations(imageWithName, imageName);
}
// 不能在分類中重寫系統方法imageNamed,
// 因為會把系統的功能給覆蓋掉,而且分類中不能調用super.
// 既能加載圖片又能打印
+ (instancetype)imageWithName:(NSString *)name{
// 這里調用imageWithName,相當于調用imageNamed
// 因為這里已經將方法完成了交換
UIImage *image = [self imageWithName:name];
if (image == nil) {
NSLog(@"加載空的圖片");
}
return image;
}
@end