delegate和block的作用都是用于兩個類之間的回傳數(shù)據(jù),即當(dāng)一個類創(chuàng)建了另一個類的實例的時候,想從被創(chuàng)建的類傳遞信息到創(chuàng)建它的類(例:比較常見的是,tableview類中創(chuàng)建的cell類想將cell類的事件傳遞到tableview類,例2:修改信息的頁面,比如修改用戶名是點擊用戶名回到下一級頁面修改,修改后返回到本級。也要用的數(shù)據(jù)的回傳)。
a、delegate和block的差別:
1、delegate運行成本低。block成本很高的。
block出棧需要將使用的數(shù)據(jù)從棧內(nèi)存拷貝到堆內(nèi)存,當(dāng)然對象的話就是加計數(shù),使用完或者block置nil后才消除;delegate只是保存了一個對象指針,直接回調(diào),沒有額外消耗。相對C的函數(shù)指針,只多做了一個查表動作 。
b、delegate的寫法:delegate的標(biāo)準(zhǔn)書寫分為幾部
一、聲明代理的類中
1.聲明一個delegate:
2.寫入代理方法
3.引入代理屬性
4.書寫判定數(shù)組
5使用代理
二、實習(xí)代理的類
1.創(chuàng)建有代理的實例
2.聲明代理在這個類中實現(xiàn)
3,具體實現(xiàn)代理
總結(jié)說的比較細(xì),但是繁瑣應(yīng)該都是看不懂,下面有例子咱們對照的看。
例:
@protocolDelegateTest //聲明一個delegate:
@optional ? ? //聲明代理方法是必須實現(xiàn)的,還是不必須實現(xiàn)的
-(void)delegateTest:(NSString*)string; ? ? //代理方法
@end ? ? //代理結(jié)束
總結(jié):上面這個部分是創(chuàng)建一個delegate,一般的書寫位置在需要代理的類的.h的文件?;蛘咝陆ㄒ粋€h文件(一般選用第一種,第二中會導(dǎo)致文件太多比較亂)
@protocolDelegateTest; ? ? //在需要代理的類引用delegate
@interfaceNextViewController :UIViewController
/**
*? delegate屬性
*/
@property(nonatomic,weak)id delegate; ? ?//創(chuàng)建delegate屬性,注意使用weak修飾符
總結(jié):以上兩部分。h文件結(jié)束
@interfaceNextViewController(){
/**
*創(chuàng)建delegate判斷用的結(jié)構(gòu)體用于判斷delegate是否被實現(xiàn),作用防止程序crash
*/
struct{
unsignedint__deleteTest :1;//一個方法對于一個。其中unsigned表示無符號,:1表示一字節(jié)。(個人疑惑,為什么不使用bool變量)
}_delegateStruct;
}
-(void)setDelegate:(id)delegate{
_delegate= delegate;
_delegateStruct.__deleteTest= [_delegaterespondsToSelector:@selector(delegateTest:)]; ? ? //一個方法對于一個
}
總結(jié):對代理的保護(hù)工作,當(dāng)使用代理的時候會判斷代理方法是否被實現(xiàn)。并個結(jié)構(gòu)體中的方法對已屬性賦值1或0.
if(_delegateStruct.__deleteTest) { ? ? //代理被實現(xiàn)就調(diào)用,沒被實現(xiàn)就不調(diào)用。(如果沒被實現(xiàn)調(diào)用,會引起程序crash)
[_delegatedelegateTest:@"delegate"]; ? ? //調(diào)用代理方法
}
總結(jié):在用觸發(fā)代理方法的地方使用代理方法。
以上是寫入代理的類下面是實現(xiàn)代理的類
NextViewController* nextVc = [NextViewControllernew]; ? ? //這個是上面那個類的實例
nextVc.delegate=self; ? ? //對有代理類的實例聲明其代理為當(dāng)前類
[self.navigationControllerpushViewController:nextVcanimated:YES];
@interfaceViewController() ? ? //在類上面寫上要實現(xiàn)的代理
#pragma mark - DelegateTest
/**
*實現(xiàn)代理方法
*/
-(void)delegateTest:(NSString*)string{
_label.text= string;
}
總結(jié):這一部分和調(diào)用系統(tǒng)的代理一個過程,不加以詳細(xì)說明
c。block的寫法
1.創(chuàng)建一個block,創(chuàng)建位置在需要block的類的
#import
typedefvoid(^BlockTest)(NSString* string); ? ? //創(chuàng)建的block(創(chuàng)建方法推薦使用Xcode右下角代碼塊生成,簡單快速)
returnType返回值類型。name是block的名字,arguments是要傳遞的參數(shù)
@interfaceNextViewController :UIViewController
總結(jié):有蘋果封裝的代碼塊block寫起來變得特別簡單
2.聲明block屬性
/**
*? block屬性
*/
@property(nonatomic,copy)BlockTestblock; ? ? //注意block屬性要用copy修飾
3.block的使用
if(_block) { ? ? ? ? ?//判斷block是否被實現(xiàn)
_block(@"block"); ? ? //調(diào)用block
}
4.block的實現(xiàn)
NextViewController* nextVc = [NextViewControllernew];
nextVc.block= ^(NSString* string){ //在創(chuàng)建實例后直接寫入block回調(diào),在block觸發(fā)后就會回到block里面
_label.text= string;
};
總結(jié):block的寫法比delegate簡單的多但是功能性不高在咱們這種項目中也不用太考慮性能,所以用哪個都一樣