類目,延展,和協(xié)議,代理

為什么使用類目
是一種為現(xiàn)有的類添加新方法的方式
有時需要對現(xiàn)有的類添加一些方法,之前都是通過繼承相關(guān)的類,然后再子類中擴(kuò)展我們需要的相應(yīng)的方法.
Objective-C是一種動態(tài)語言,可以給現(xiàn)有的類添加新的方法,這便是對類目的延展.

類目(category):為已知的類添加新的方法计呈,無論是否知道類的源代碼,這些類包括自己定義的類和系統(tǒng)已有的類。
類目的作用主要有三個方面:
1、將類的實(shí)現(xiàn)分散到多個不同的文件中,將多個類目的聲明放入同一個.h文件中闷畸,將實(shí)現(xiàn)放入多個.m方法中。
2、使用類目創(chuàng)建對私有方法的前向引用乎完,就是為類創(chuàng)建私有方法。
3品洛、向?qū)ο筇砑臃钦絽f(xié)議树姨,現(xiàn)在逐漸被正式協(xié)議做替代。

Paste_Image.png
Paste_Image.png
Paste_Image.png

類目的實(shí)現(xiàn)
類目聲明之后需要對類擴(kuò)展出來的方法進(jìn)行實(shí)現(xiàn)

Paste_Image.png

使用擴(kuò)展后的方法

#import <Foundation/Foundation.h>
#import "NSString+MyNumber.h"http://添加類目頭文件
int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        //創(chuàng)建四個字符串
        NSString *str1=@"gdsfgsdfgfdgdfs";
        NSString *str2=@"fgsagsdfgfdsg";
        NSString *str3=@"打開分為飛大廈俄方飛";
        NSString *str4=@"jfghjfghjfghj";
        
        //求出每一個字符串的長度
//        int l1=(int)[str1 length];
//        int l2=(int)[str2 length];
//        int l3=(int)[str3 length];
//        int l4=(int)[str4 length];
//        
//        //轉(zhuǎn)為對象
//        NSNumber *m1=[NSNumber numberWithInt:l1];
//        NSNumber *m2=[NSNumber numberWithInt:l2];
//        NSNumber *m3=[NSNumber numberWithInt:l3];
//        NSNumber *m4=[NSNumber numberWithInt:l4];
        
        //創(chuàng)建一個可變的字典
        NSMutableDictionary *mDic=[NSMutableDictionary new];
        
        //添加對象到字典中
//        [mDic setObject:m1 forKey:str1];
//        [mDic setObject:m2 forKey:str2];
//        [mDic setObject:m3 forKey:str3];
//        [mDic setObject:m4 forKey:str4];
        
        //使用類目后修改為
        [mDic setObject:[str1 getStrLength] forKey:str1];
        [mDic setObject:[str2 getStrLength] forKey:str2];
        [mDic setObject:[str3 getStrLength] forKey:str3];
        [mDic setObject:[str4 getStrLength] forKey:str4];
        
        //輸出
        NSLog(@"%@",mDic);
    }
    return 0;
}

注意類目里面只能寫方法,不能寫聲明和屬性,所以,類目不能作為接口來用

類目的局限性
-類目無法向已有類中添加實(shí)例變量
-如果類目中的方法和已有類中的方法名稱沖突時桥状,類目中的方法優(yōu)先級高,如果方法名沖突,已有類中的原始方法便無法使用
-在使用類目的時候,最好是將自己擴(kuò)展的方法和原始方法區(qū)分開來

類目的作用
有三個方面:
1.將類的實(shí)現(xiàn)分散到多個不同的文件中
-將多個類目的聲明放入同一個.h文件中
-將實(shí)現(xiàn)放入多個.m方法中
2.使用類目創(chuàng)建對私有方法的前向引用
-就是為類創(chuàng)建私有方法
3.向?qū)ο筇砑臃钦絽f(xié)議
-現(xiàn)在逐漸被正式協(xié)議做替代

利用類目分散實(shí)現(xiàn)類
-類的@implementation部分只能寫在一個.m文件中
-對于大型的類,可以使用類目將類的實(shí)現(xiàn)間接的放入多個.m文件中
-將多個類目的聲明放入同一個.h文件中帽揪,包括多個類目聲明的@interface和@end

類私有的方法
-Objective-C中沒有絕對意義上的私有方法
-在.h文件中聲明的方法都屬于公開的方法,意味著開放給別人調(diào)用
-如果不想公開某些方法辅斟,可以不在.h文件中聲明
-這樣的方法可以被本類中的其他方法所調(diào)用
-如果在類外面強(qiáng)行調(diào)用這些未公開的方法转晰,也能調(diào)用,但是會有編譯器警告

類的延展
延展(extension):
在自己類的實(shí)現(xiàn)文件中添加類目(匿名類目)來聲明私有方法.(只有本類的.m文件中才能使用)

類的延展可以讓類方法成為類的私有方法
將私有方法聲明到一個匿名類目中,并且將這個匿名類目放到類的.m文件里
然后在類的.m的@implementation部分將這個匿名類目中的私有方法進(jìn)行實(shí)現(xiàn)
這樣的也能夠?qū)懗鏊接蟹椒ú樾希峭瑯右部梢詮?qiáng)行在類外部調(diào)用蔗崎,也會有編譯器警告

使用類目對私有方法反向引用

-如果私有方法的聲明放入一個匿名類目中,并且這個類目放入一個.h文件中那么這個.h文件可以看做私有的API
-私有API可以不公開侠坎,只開放給許可者來調(diào)用
然后在使用私有API時將那個.h文件導(dǎo)入蚁趁,然后調(diào)用私有方法,編譯器警告便會消失

respondsToSelector
用來檢查某一個對象能否調(diào)用某一個方法(檢查方法時候有實(shí)現(xiàn))
創(chuàng)建了NSObject的類目之后实胸,類目中聲明方法對于NSObject的子類來說如何檢查是否實(shí)現(xiàn)了哪個方法
因?yàn)榭赡芤{(diào)用某個NSObject類目中聲明的方法他嫡,在調(diào)用時需要判斷是否能夠響應(yīng)才行,否則會造成程序崩潰

MyClass *mc= [MyClass new];
if([mc respondsToSelector:@selector(test)])
{
            [mc test];
}
else
{
        NSLog(@"未實(shí)現(xiàn)test方法庐完!");
}

Objective-C中的協(xié)議
協(xié)議是一個方法列表钢属,采用協(xié)議時需要在聲明類時說明要采用的協(xié)議

協(xié)議的聲明
協(xié)議就是一種標(biāo)準(zhǔn),用來定義了實(shí)現(xiàn)什么,不關(guān)心具體怎么實(shí)現(xiàn)
OC的協(xié)議是由@protocol聲明的一組方法列表
要求其它的類去實(shí)現(xiàn)门躯,相當(dāng)于@interface部分的聲明

@required標(biāo)注的方法為必須實(shí)現(xiàn)方法(默認(rèn)不寫為必須實(shí)現(xiàn))
@optional標(biāo)注的方法為可以選擇實(shí)現(xiàn)

@protocol 協(xié)議名稱
//方法列表
 @end

協(xié)議的實(shí)現(xiàn)
方式:
接口文件 一個類可以通過協(xié)議,用來遵循多個類中的方法,這樣可以做到多繼承的效果

@interface ClassName : 父類名 <協(xié)議1,協(xié)議2…>
@end

實(shí)現(xiàn)文件

@implementation ClassName
    //實(shí)現(xiàn)協(xié)議中的方法
@end

具體實(shí)現(xiàn)方法

@protocol MyProtocol <NSObject>
@required//必須實(shí)現(xiàn)
-(int) addX:(int) x andY:(int) y;
@optional//可選實(shí)現(xiàn)
-(int) substructX:(int) x andY:(int) y;
@end

協(xié)議和數(shù)據(jù)類型
聲明實(shí)例變量或方法可以指定協(xié)議名稱
id類型可以指向任何類型的

@interface MyClass
{
    id<MyProtocol> myVar; 
}
@end

要求傳入的參數(shù)必須采用MyProtocol協(xié)議

 -(void) methodName:(id<MyProtocol>) obj
{
    //方法代碼
}

檢查對象是否實(shí)現(xiàn)了某個協(xié)議
可以通過對象的下列方法來判斷是否遵循某協(xié)議(confrorms:遵守)

conformsToProtocol:@protocol (協(xié)議名)

在此創(chuàng)建一個代理使用的實(shí)例
先創(chuàng)建兩個類,繼承NSObjective
一個被代理的類,命名為HouseMan
一個代理的類,命名Medium

HouseMan.h接口文件中實(shí)現(xiàn)

//  房東
#import <Foundation/Foundation.h>

//1.聲明協(xié)議
@protocol GetHoseProtocol <NSObject>

-(void)getRent;//房租的方法
@end
@interface HouseMan : NSObject

//2.創(chuàng)建一個代理人的屬性 在此簽訂一個協(xié)議
@property(nonatomic,assign)id<GetHoseProtocol> delegate;

//3.協(xié)議的方法
-(void)houseRent;

@end

HouseMan.m實(shí)現(xiàn)文件中實(shí)現(xiàn)

//4.實(shí)現(xiàn)需要代理的方法
-(void)houseRent
{
    [self.delegate getRent];//呼叫被代理人去做
}

Medium.h接口文件中實(shí)現(xiàn)


#import <Foundation/Foundation.h>

#import "HouseMan.h"http://5.包含代理人的頭文件

@interface Medium : NSObject<GetHoseProtocol>//6.被代理人和代理人簽訂協(xié)議

//7聲明代理人的屬性
@property (nonatomic, strong) NSString *name;

Medium.m實(shí)現(xiàn)文件中

#import "Medium.h"

@implementation Medium

//7.實(shí)現(xiàn)被代理人的方法
-(void)getRent
{
    NSLog(@"正在收房租");
}

@end

最后在main.m文件中

#import <Foundation/Foundation.h>

//包含頭文件
#import "HouseMan.h"
#import "Medium.h"

int main(int argc, const char * argv[]) 
{
    @autoreleasepool
    {
        //創(chuàng)建代理對象
        Medium *m=[Medium new];
        m.name=@"房屋中介";
        
        //創(chuàng)建被代理對象
        HouseMan *h=[HouseMan new];
        
        //給代理對象賦值
        h.delegate=m;
        
        //被代理人呼叫代理人實(shí)現(xiàn)方法 這個方法是在被代理人種實(shí)現(xiàn)的
        [h houseRent];   
    }
    return 0;
}

設(shè)計模式

設(shè)計模式(Design pattern)是一套被反復(fù)使用淆党、多數(shù)人知曉的、經(jīng)過分類編目的讶凉、代碼設(shè)計經(jīng)驗(yàn)的總結(jié)染乌。

-設(shè)計模式是某個具體編程問題的通用化,可以復(fù)用的解決方案
-沒有一種可以從前一個方案中完全復(fù)用代碼的情況懂讯,但是可以使用前一次的解決問題時使用的思想
-設(shè)計模式可以在遇到編程問題時會想起一個正確的解決方案
-常見的設(shè)計模式有:單例模式荷憋、委托(代理)模式、觀察者模式褐望、職責(zé)鏈模式等等

委托模式
在委托模式中勒庄,程序中的一個對象代表另外一個對象執(zhí)行某個動作,或者與之相互協(xié)作共同完成某個任務(wù)。
Cocoa Touch廣泛使用委托(delegate)瘫里,它是負(fù)責(zé)為其他對象處理特定任務(wù)的類实蔽。通過委托,我們能夠在某些預(yù)定義時間內(nèi)為發(fā)布委托的類做一些工作谨读。

所謂代理局装,就是指一方授予他方代理權(quán),他方依代理權(quán)與第三方進(jìn)行法律行為劳殖,其行為后果由一方承擔(dān)的一種民事法律制度贼邓。委托是一方將一定的事務(wù)委諸于另一方實(shí)施的法律制度。

委托和代理的區(qū)別:
第一闷尿,委托規(guī)范的是委托人和受托人雙方之間的關(guān)系塑径;而代理規(guī)范的是本人、代理人和第三人的關(guān)系填具。
第二统舀,代理關(guān)系中代理人代理的對象是進(jìn)行意思表示和接受意思表示的行為匆骗;而委托中受托人代為實(shí)施的行為可以是法律行為,也可以是事實(shí)行為誉简。
第三碉就,代理包括對內(nèi)和對外兩種關(guān)系,對內(nèi)是代理人和被代理人之間的關(guān)系闷串,而對外是代理人和第三人之間的關(guān)系瓮钥;而委托只是委托人和受托人之間的關(guān)系。

簡單的總結(jié):
-委托就是有兩個對象,一個變化時,另外一個能夠知道上面一個的變化.
-一個對象保存另外一個對象的引用,被引用的對象實(shí)現(xiàn)事先確定的協(xié)議,這個協(xié)議用來把對象中的變化通知給被引用的對象
-委托不一定使用到協(xié)議,使用類目一樣能完成,或者協(xié)議類目都不知用,同樣能做到.

delegate屬性都是assign而不是retain為了避免循環(huán)引用造成的內(nèi)存泄露烹吵。
循環(huán)引用的問題這樣理解:
-比如在main函數(shù)中創(chuàng)建了兩個類的對象A和B碉熄,現(xiàn)在引用計數(shù)都是1。現(xiàn)在讓A和B互相引用(A有一個屬性是B對象肋拔,屬性說明是retain锈津;B有一個屬性是A對象,屬性說明是retain)凉蜂,現(xiàn)在兩個對象的引用計數(shù)都增加了1琼梆,都變成了2。
-現(xiàn)在執(zhí)行 [A release]; [B release]; 此時創(chuàng)建對象的main函數(shù)已經(jīng)釋放了自己對對象的所有權(quán)窿吩,但是此時A和B的引用計數(shù)都還是1茎杂,因?yàn)樗麄兓ハ嘁昧恕?br> -這時你發(fā)現(xiàn)A和B將無法釋放,因?yàn)橐脶尫臕必須先釋放B纫雁,在B的dealloc方法中再釋放A煌往。同理,要想釋放B必須先釋放A先较,在A的dealloc方法中再釋放B携冤。所以這兩個對象將一直存在在內(nèi)存中而不釋放悼粮。這就是所謂的循環(huán)引用的問題闲勺。
-要想解決這個問題,一般的方法可以將引用的屬性設(shè)置為assign,而不是retain來處理扣猫。

使用非正式協(xié)議的委托模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菜循,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子申尤,更是在濱河造成了極大的恐慌癌幕,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昧穿,死亡現(xiàn)場離奇詭異勺远,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)时鸵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門胶逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厅瞎,“玉大人,你說我怎么就攤上這事初坠『汪ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵碟刺,是天一觀的道長锁保。 經(jīng)常有香客問我,道長半沽,這世上最難降的妖魔是什么爽柒? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任抄囚,我火速辦了婚禮霉赡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘幔托。我一直安慰自己穴亏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布重挑。 她就那樣靜靜地躺著嗓化,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谬哀。 梳的紋絲不亂的頭發(fā)上刺覆,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音史煎,去河邊找鬼谦屑。 笑死,一個胖子當(dāng)著我的面吹牛篇梭,可吹牛的內(nèi)容都是我干的氢橙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恬偷,長吁一口氣:“原來是場噩夢啊……” “哼悍手!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袍患,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤坦康,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诡延,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滞欠,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年肆良,在試婚紗的時候發(fā)現(xiàn)自己被綠了筛璧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赤兴。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖隧哮,靈堂內(nèi)的尸體忽然破棺而出桶良,到底是詐尸還是另有隱情,我是刑警寧澤沮翔,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布陨帆,位于F島的核電站,受9級特大地震影響采蚀,放射性物質(zhì)發(fā)生泄漏疲牵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一榆鼠、第九天 我趴在偏房一處隱蔽的房頂上張望纲爸。 院中可真熱鬧,春花似錦妆够、人聲如沸识啦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颓哮。三九已至,卻和暖如春鸵荠,著一層夾襖步出監(jiān)牢的瞬間冕茅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工蛹找, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姨伤,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓庸疾,卻偏偏與公主長得像乍楚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子彼硫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1.項(xiàng)目經(jīng)驗(yàn) 2.基礎(chǔ)問題 3.指南認(rèn)識 4.解決思路 ios開發(fā)三大塊: 1.Oc基礎(chǔ) 2.CocoaTouch...
    陽光的大男孩兒閱讀 4,984評論 0 13
  • 1.OC里用到集合類是什么炊豪? 基本類型為:NSArray凌箕,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,374評論 0 3
  • 1拧篮、Objective-C的類可以多重繼承么?可以采用多個協(xié)議么牵舱?答:不可以多重繼承串绩,可以采用多個協(xié)議。2芜壁、#im...
    亦晴工作室閱讀 644評論 0 0
  • 你偷走了今日的太陽 已經(jīng)八點(diǎn)還是黑暗一片 我摸黑起來穿好衣服洗漱 等著你過來 你不來 我又回到床上繼續(xù)睡覺 你偷走...
    初五閱讀 10,152評論 3 13
  • 心情很差礁凡。工作生活和情感高氮。 站在別人的角度和站在自己的角度,有時候人就是那么自私顷牌,我還沒有說什么剪芍,你就斷定我會跟你...
    荇菜閱讀 254評論 0 1