iOS基礎03--category & extension & protocol

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)。

可以去github上查看Demo,喜歡的話star一下哦
github
CSDN

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容