- 代理屬于一種設(shè)計模式,跟通知相似,內(nèi)部發(fā)生的一些事情可以告訴別人
- 通知屬于觀察者模式:一直在那盯著,一旦有人發(fā)出通知,就捕獲通知,執(zhí)行一系列的操作
- 代理和通知這兩種模式都屬于數(shù)據(jù)傳遞
delegate
- 代理一般使用_weak
-
為了保證任何對象都可以做為代理,所以類型不要寫死,用_id
Warning:
- 如果讓一個控件/控制器成為了代理,那么耦合性會特別強.表現(xiàn)為你離不開我,我離不開你.
- 誰觸動了代理方法就把誰傳出去
代理方法的命名:
- XXX發(fā)生了什么事情,就把誰(參數(shù))傳出去
比如: -
scrollView觸發(fā)了滾動事件,把scrollView傳出去
-
scrollView觸發(fā)了移動事件,把scrollView傳出去,在把對應(yīng)的參數(shù)傳出去
.
代理設(shè)計模式的作用:
- A對象監(jiān)聽B對象的一些行為,A成為B的代理
- B對象想告訴A對象一些事情抠刺,A成為B的代理
代理設(shè)計模式的總結(jié):
- 如果你想監(jiān)聽別人的一些行為包斑,那么你就要成為別人的代理
- 如果你想告訴別人一些事情,那么就讓別人成為你的代理
代理設(shè)計模式的開發(fā)步驟
- 擬一份協(xié)議(協(xié)議名字的格式:控件名 + Delegate)
在協(xié)議里面聲明一些代理方法(一般代理方法都是@optional) - 聲明一個代理屬性:@property (nonatomic, weak) id<代理協(xié)議> delegate;
- 在內(nèi)部發(fā)生某些行為時渠欺,調(diào)用代理對應(yīng)的代理方法妹蔽,通知代理內(nèi)部發(fā)生什么事
- 設(shè)置代理:xxx.delegate = yyy;
- yyy對象遵守協(xié)議,實現(xiàn)代理方法
代理和通知的區(qū)別
- 代理:1個對象只能告訴另1個對象發(fā)生了什么事
- 通知:1個對象可以告訴N個對象發(fā)生了什么事
實例:
- 現(xiàn)在有一個被封裝起來的點擊加載更多(clickUpLoadMore)的功能
- 要實現(xiàn)的是:想在點擊點擊加載更多(clickUpLoadMore)后刷新新的數(shù)據(jù)
解放方案:
首先要擬一份協(xié)議:
-
clickUpLoadMore中把寫出一個代理的成員屬性
-
寫一個協(xié)議必要的3項:
2-1:由于是在@interface上面寫的所以要@class聲明這個類.
2-2:@protocol 代理名稱(一般用類的全稱+Delegate)<NSObject>
2-3:@optional: 寫一個需要實現(xiàn)的方法
-
在.m文件中的加載更多的方法中判斷下是否遵守了協(xié)議,如果遵守了協(xié)議,就可以使用代理中的方法.
- 讓控制器成為被封裝起來的clickUpLoadMore的_代理
-
并且遵守協(xié)議
-
最后一步,就是實現(xiàn)代理中的方法即可
代理為什么要使用weak屬性
__Warning: 事例1:
- 控制器中有個retain強指著tableView
- tableView中的代理也是有個強指針的delegate
-
但此時tableView的代理是控制器,如果互相強引用的話就不會都不會死.
__解決方案: 讓代理是weak(弱引用)就不會出現(xiàn)這種情況,如果不使用weak,可能導(dǎo)致控制器和代理永遠無法銷毀.
__Warning: 事例1:
1. 控制器中有個retain強指著tableView
2. tableView中的代理也是有個強指針的subViews
3. subViews中裝著footView 而像操控footView的話必須通過代理方法,(代理一般都是控制器)如果代理使用強引用的話,都不會死掉.
__所以要用weak,控制器外界如果沒有被強引用,其他的都會死掉.