iOS基礎03--category & extension & protocol
Category(分類)
先來一波代碼看看 category
@interface Person : NSObject
- (void)printName;
@end
@interface Person (category)
- (void)printName;
+ (id)shareMange;
@end
static Person * _shareInstance;
@implementation Person
- (void)printName{
NSLog(@"print Person");
}
@end
@implementation Person (category)
- (void)printName{
NSLog(@"print Person (category)");
}
+ (id)shareMange{
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
_shareInstance = [[Person alloc]init];
});
return _shareInstance;
}
@end
特性1:category 可以增加實例方法和類方法;(雖然無法添加成員變量是因為runtime時objc_class結構體的大小是沒法改變的,但是objc_class的方法鏈表是一個二維指針,雖然也是不能改變大小,但是可以改變內(nèi)存區(qū)域的值,讓它達到動態(tài)添加方法的目的)
特性2:category 添加的方法會覆蓋掉原來的方法(實際上不是覆蓋掉,而是在運行時從類的結構體的方法列表中查找的時候,category方法添加的列表是在上面的,所以就會先掉用category的方法),優(yōu)先級是:分類方法-->原來類的方法-->原來類的父類的方法;如果子類的類別或者子類本身也添加了和父類的類別同樣的方法,優(yōu)先級也是差不多,先考慮自身的列表,然后才查父類的方法列表,就是:子類分類方法-->子類實現(xiàn)的方法-->父類分類方法-->父類實現(xiàn)方法;
特性3:category添加的方法,子類是可以繼承的;
特性4:category是在運行時加載的;
特性5:category不能添加成員變量(屬性);因為category是在runtime的時候加載的,class類型指針在runtime的時候是指向一個objc_class結構體的。而結構體本身大小是固定的。所以編譯的時候是沒法加成員變量的。但是用runtime是可以給它添加屬性的,而這樣添加屬性和給原來的類本身添加屬性性質(zhì)是一樣的。
面試題:category實現(xiàn)的方法是放在哪的?
//
那接下來,就用runtime實現(xiàn)一下給category添加屬性
@interface Person (category)
@property (nonatomic,copy)NSString * name;
@end
#import <objc/message.h>
@implementation Person (category)
- (void)setName:(NSString *)name{
objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self, "name");
}
@end
Extension (擴展)
extension其實就是只有一個.h文件。一般我們是把它放到類的.m文件中使用。一般私有的成員變量、屬性、方法可以通過extension在.m文件中聲明。然后extension是編譯的時候檢查的。如果在.m文件中通過extension實現(xiàn)了一些私有方法和屬性,那么在外面使用的時候就會馬上報告錯誤。其次extension是必須有一個類的源碼才可以添加的。所以一些系統(tǒng)類,比如NSString是沒法添加擴展的。
@interface Person ()
@property (nonatomic, copy) NSString * className;
@end
@implementation Person
@end
category是可以被繼承的。而extension是不可以被繼承的,通常是為了實現(xiàn)私有方法、屬性才用到的。
protocol(協(xié)議)
protocol就是協(xié)議。面試經(jīng)常問到的多繼承問題:OC無法實現(xiàn)多繼承,但是可以通過protocol實現(xiàn)。