天天看點

代理傳值與塊代碼傳值

主線程與子線程經常需要進行資料的傳遞,不同的類之間,不同的控制器之間都需要。

而且經常需要監聽一個動作的完成,而後才去做相應事件。(代理是一對一的關系)。

一、代理傳值

代理是一種設計模式。iOS中用的非常多。可以通過自定義代理來進行傳值。

參見我的這篇文章 http://blog.csdn.net/xn4545945/article/details/31036523

在iOS中,委托方與被委托方都要實作3個步驟。(見代碼注釋)

下面代碼:模拟下載下傳完成後需要更新UI. 用代理來傳值.

XNUpload.h

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import <Foundation/Foundation.h>  
  2. //1.定義代理協定  
  3. @protocol XNUploadDelegate <NSObject>  
  4. - (void)downloadFinshed:(NSString *)param;  
  5. @end  
  6. @interface XNUpload : NSObject  
  7. //2.定義代理屬性  
  8. @property (nonatomic, assign) id <XNUploadDelegate> delegate;  
  9. -(void)download;  
  10. @end  

XNUpload.m

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import "XNUpload.h"  
  2. @implementation XNUpload  
  3. - (void)download {  
  4.     NSLog(@"正在下載下傳....");  
  5.     sleep(3.0);  
  6.     NSLog(@"下載下傳完成!");  
  7.     //3.往主線程中更新UI, 需要傳遞參數. 通知主線程下載下傳完成. (調用代理方法)  
  8.     [self.delegate downloadFinshed:@"下載下傳完成啦!"];  
  9. }  
  10. @end  

XNViewController.m

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import "XNViewController.h"  
  2. #import "XNUpload.h"  
  3. @interface XNViewController () <XNUploadDelegate> //1. 遵守代理協定  
  4. @end  
  5. @implementation XNViewController  
  6. - (void)viewDidLoad {  
  7.     [super viewDidLoad];  
  8.     XNUpload *upload = [[XNUpload alloc] init];  
  9.     [upload download];   //下載下傳了  
  10.     //2. 設定代理  
  11.     upload.delegate = self;  
  12. }  
  13. //3.實作代理方法. 這個方法裡面就表明下載下傳完成了.  
  14. - (void)downloadFinshed:(NSString *)param {  
  15.     NSLog(@"%@", param);  
  16. }  
  17. @end  

二、塊代碼傳值

塊代碼傳值更加簡便,且代碼更加緊湊,更友善。多線程中用塊代碼更加普遍。

使用注意  : 1. 當不設定 block 而 傳入 nil 時 , 會報野指針 exc bad access.   ( 解決 : 判斷一下 , if(xx){ .. }) 2. block 中 執行應該回主線程 去更新 UI, 到裡面 dispatch 一下 . 3 . 蘋果建議所有的 塊代碼定義 都 不要 放在 頭檔案 中 . ( 解決 : 直接在使用塊代碼的 來個匿名的 就 OK) * 好處 : 能 避免 自己定義的塊代碼名與蘋果内置的 沖突重名 .

代碼如下: XNUpload.h

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import <Foundation/Foundation.h>  
  2. @interface XNUpload : NSObject  
  3. - (void)download:(void (^)(NSString *param))completion;  
  4. @end  

XNUpload.m

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import "XNUpload.h"  
  2. @implementation XNUpload  
  3. - (void)download:(void (^)(NSString *param))completion { //1.在參數中定義塊代碼  
  4.     NSLog(@"正在下載下傳....");  
  5.     sleep(3.0);  
  6.     NSLog(@"下載下傳完成!");  
  7.     //往主線程中更新UI, 需要傳遞參數. 通知主線程下載下傳完成. (使用塊代碼)  
  8.     if (completion) {  
  9.         //這樣可以讓調用者不用關心線程問題  
  10.         dispatch_async(dispatch_get_main_queue(), ^{  
  11.             completion(@"下載下傳完成!");  //2.執行塊代碼  
  12.         });  
  13.     }  
  14. }  
  15. @end  

XNViewController.m

[objc]  view plain copy

代理傳值與塊代碼傳值
代理傳值與塊代碼傳值
  1. #import "XNViewController.h"  
  2. #import "XNUpload.h"  
  3. @interface XNViewController ()  
  4. @end  
  5. @implementation XNViewController  
  6. - (void)viewDidLoad {  
  7.     [super viewDidLoad];  
  8.     XNUpload *upload = [[XNUpload alloc] init];  
  9.     //直接調用方法即可  
  10.     [upload download: ^(NSString *param) {  
  11.         NSLog(@"%@", [NSThread currentThread]);  
  12.         NSLog(@"%@", param);  
  13.     }];  
  14. }  
  15. @end  

塊代碼與代理比較,用起來簡單很多,很友善。

轉載請注明出處:http://blog.csdn.net/xn4545945