一、Category
Category在iOS開發(fā)中使用頻繁,尤其在為系統(tǒng)類進行拓展的時候,我們可以不用繼承系統(tǒng)類,直接給系統(tǒng)類添加方法,最大程度體現(xiàn)了Objective-C的動態(tài)語言特性。
注意事項
1:類別是類的擴展,只可以聲明方法,不可以聲明變量(runtime搞)。并且,類別的方法優(yōu)先級較高,可覆蓋原類方法。
2:類別的方法中,不可以調(diào)用super方法。--類別的局限
3:category 方法不能覆蓋于同一class 的其它 category中的方法。因為不法預(yù)知他們的加載優(yōu)先順序,就可能在編譯時出錯。
使用類別:
1。對框架提供類的擴展(沒有源碼,不能修改)。
2。 不想生成一個新的子類的情況下,比如對NSArray 的擴展。
3。方便做項目管理,可以將一份源碼在多個地方共享或者做方法版本管理、多人協(xié)作開發(fā)、用本地版本替換公共版本實現(xiàn)。
#import
@interface NSObject (Category)
- (void)myMethod;
@end
使用Category需要注意的點:
1.Category的方法不一定非要在@implementation中實現(xiàn),也可以在其他位置實現(xiàn),但是當調(diào)用Category的方法時,依據(jù)繼承樹沒有找到該方法的實現(xiàn),程序會崩潰。
2.Category理論上不能添加變量,但是可以使用@dynamic來彌補這種不足。
??2.1 @dynamic的作用就是禁止編譯器為@property產(chǎn)生setter和getter方法,有兩種辦法實現(xiàn)setter和getter方法 1.自己提供setter和getter方法;2.方法動態(tài)決議(DynamicMethod Resolution)dynamic參考鏈接http://blog.csdn.net/daydreamingboy/article/details/22682851
??擴展@synthesize的作用就是讓編譯器自動生成setter和getter方法,還有一個作用,可以指定與屬性對應(yīng)的實例變量,例如@synthesize myButton = xxx; 那么self.myButton其實是操作的實例變量xxx,而不是_myButton了。
實際項目中有這么寫的
@synthesize myButton;
這樣寫了之后,那么編譯器會自動生成myButton的實例變量,以及相應(yīng)的getter和setter方法。注意:_myButton這個實例變量是不存在的,因為自動生成的實例變量為myButton而不是_myButton,所以現(xiàn)在@synthesize的作用就相當于指定實例變量;
如果.m文件中寫了@synthesize myButton;那么生成的實例變量就是myButton;如果沒寫@synthesize myButton;那么生成的實例變量就是_myButton
#import
static const voidvoid * externVariableKey =&externVariableKey;
@implementation NSObject (Category)
@dynamic variable;
- (id) variable
{
return objc_getAssociatedObject(self, externVariableKey);
}
- (void)setVariable:(id) variable
{
objc_setAssociatedObject(self, externVariableKey, variable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
增加屬性方法
.h文件
//分類的頭文件
@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end
.m文件
//實現(xiàn)文件
#import "ClassName + CategoryName.h"
#import <objc/runtime.h>
static void *strKey = &strKey;
@implementation ClassName (CategoryName)
-(void)setStr:(NSString *)str
{
objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}
-(NSString *)str
{
return objc_getAssociatedObject(self, &strKey);
}
@end
在setStr:方法中使用了一個objc_setAssociatedObject的方法,這個方法有四個參數(shù),分別是:源對象,關(guān)聯(lián)時的用來標記是哪一個屬性的key(因為你可能要添加很多屬性),關(guān)聯(lián)的對象和一個關(guān)聯(lián)策略。
用來標記是哪一個屬性的key常見有三種寫法,但代碼效果是一樣的,如下:
//利用靜態(tài)變量地址唯一不變的特性
1、static void *strKey = &strKey;
2、static NSString *strKey = @"strKey";
3、static char strKey;
關(guān)聯(lián)策略是個枚舉值,解釋如下:
enum {
OBJC_ASSOCIATION_ASSIGN = 0, //關(guān)聯(lián)對象的屬性是弱引用
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //關(guān)聯(lián)對象的屬性是強引用并且關(guān)聯(lián)對象不使用原子性
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象不使用原子性
OBJC_ASSOCIATION_RETAIN = 01401, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
OBJC_ASSOCIATION_COPY = 01403 //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
};
http://www.itdecent.cn/p/3cbab68fb856
類別幾個作用:
- 擴展已有的類。
- 引用父類未公開方法。
- 實現(xiàn)簡單協(xié)議。
http://www.itdecent.cn/p/2bf61807b6b3
二、Extension
Extension非常像是沒有命名的類別,即匿名類別
作用:
1.能為某個類附加額外的屬性,成員變量,方法聲明
2.一般的擴展寫到.m文件中(@implementation的上方)
3.一般的私有屬性寫到類擴展
使用格式
@interface Mitchell()
//屬性
//方法
@end
使用Extension注意的點:
Extension中的方法必須在@implementaion中實現(xiàn),否則編譯會報錯。
三、Category和Extension區(qū)別
