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