iOS類別(Category)添加自定義屬性、擴展(Extension)

category and extension的官方文檔

  • 類別的作用
  1. 將類的實現(xiàn)分散到多個不同文件或多個不同框架中:相當于文件瘦身(把類似作用的方法整理一塊)方便代碼管理
  2. 創(chuàng)建對私有方法的前向引用:如果其他類中的方法未實現(xiàn),在你訪問其他類的私有方法時編譯器報錯這時使用類別,在類別中聲明這些方法(不必提供方法實現(xiàn)),編譯器就不會再產(chǎn)生警告
  3. 向?qū)ο筇砑臃钦絽f(xié)議:創(chuàng)建一個NSObject的類別稱為 “創(chuàng)建一個非正式協(xié)議”,因為可以作為任何類的委托對象使用(當類別所在類和引用該類別的類同時實現(xiàn)一個方法時優(yōu)先調(diào)用類別類的實現(xiàn)方法)
  • 類別使用場景
  1. 類包含了很多個方法實現(xiàn),而這些方法需要不同團隊的成員來實現(xiàn)
  2. 當你在使用基礎(chǔ)類庫中的類時,你不想繼承這些類而只想添加一些方法時。
  3. 調(diào)用其他類的私有方法
  4. 當非正式協(xié)議使用
  • 舉例說明
#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end
  • 類別添加自定義屬性
    當向類別中添加自定義屬性時會報instance variables may not be placed in categories錯誤
@interface LMReadingVC (Helper)<UIToolbarDelegate>
{
NSString *topbar;/*報錯instance variables may not be placed in categories */
}

正確添加方法

@interface NSObject (XY)
@property (nonatomic, strong) id                tempObject;
@end

@implementation NSObject (XY)

@dynamic tempObject;
- (id)tempObject
- {
  id object = objc_getAssociatedObject(self,NSObject_key_tempObject);
  return object;
}
- (void)setTempObject:(id)tempObject
{
[self willChangeValueForKey:@"tempObject"];
objc_setAssociatedObject(self, NSObject_key_tempObject, tempObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self didChangeValueForKey:@"tempObject"];
}
@end

Extension簡要說明

Extension非常像是沒有命名的類別。

@interface MyClass : NSObject 
@property (retain, readonly) float value; 
@end

//一般的時候,Extension都是放在.m文件中@implementation的上方。

@interface MyClass () 
@property (retain, readwrite) float value; 
@end

使用Extension需要注意的點:
(1) Extension中的方法必須在@implementation中實現(xiàn),否則編譯會報錯。


偷懶引用網(wǎng)友例子說明創(chuàng)建對私有方法的前向引用

 /*********person.h***********/
#import <Foundation/Foundation.h>
@interface person : NSObject
+ (void)getAge;
@end
/*********person.m***********/
#import "person.h"
@interface person ()
+ (void)getName;
@end
@implementation person
+ (void)getAge {
NSLog(@"age:18");
}
+ (void)getName {
NSLog(@"name:XXX");
}
@end

然后正常情況下別的類想要直接調(diào)用getName是調(diào)用不了的,會報錯
然后我又創(chuàng)建了一個Category,在.h里聲明方法getName,.m什么也沒寫

#import "person.h"
@interface person (TEXT)
+ (void)getName;
@end

然后在要調(diào)用的類import這個Category,再去運行上圖的代碼,就不會報錯,而且getName的私有方法也執(zhí)行了

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

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

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