【iOS】代理傳值與塊代碼傳值

主線程與子線程常常須要進行數據的傳遞,不一樣的類之間,不一樣的控制器之間都須要。設計模式

並且常常須要監聽一個動做的完成,然後纔去作相應事件。(代理是一對一的關係)。xcode

 

1、代理傳值多線程

代理是一種設計模式。iOS中用的很是多。能夠經過自定義代理來進行傳值。async

參見個人這篇文章 http://blog.csdn.net/xn4545945/article/details/31036523atom

在iOS中,委託方與被委託方都要實現3個步驟。(見代碼註釋)spa

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

 

XNUpload.h線程

 

[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import <Foundation/Foundation.h>  
  2.   
  3. //1.定義代理協議  
  4. @protocol XNUploadDelegate <NSObject>  
  5. - (void)downloadFinshed:(NSString *)param;  
  6. @end  
  7.   
  8.   
  9. @interface XNUpload : NSObject  
  10. //2.定義代理屬性  
  11. @property (nonatomic, assign) id <XNUploadDelegate> delegate;  
  12.   
  13. -(void)download;  
  14. @end  


XNUpload.m設計

 

 

[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import "XNUpload.h"  
  2.   
  3. @implementation XNUpload  
  4. /** 
  5.  *  模擬下載完成後須要更新UI 
  6.  */  
  7. - (void)download {  
  8.     NSLog(@"正在下載....");  
  9.     sleep(3.0);  
  10.     NSLog(@"下載完成!");  
  11.     //3.往主線程中更新UI, 須要傳遞參數. 通知主線程下載完成. (調用代理方法)  
  12.     [self.delegate downloadFinshed:@"下載完成啦!"];  
  13. }  
  14.   
  15. @end  


XNViewController.m代理

 

 

[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import "XNViewController.h"  
  2. #import "XNUpload.h"  
  3.   
  4. @interface XNViewController () <XNUploadDelegate> //1. 遵照代理協議  
  5.   
  6. @end  
  7.   
  8. @implementation XNViewController  
  9. - (void)viewDidLoad {  
  10.     [super viewDidLoad];  
  11.     XNUpload *upload = [[XNUpload alloc] init];  
  12.     [upload download];   //下載了  
  13.   
  14.     //2. 設置代理  
  15.     upload.delegate = self;  
  16. }  
  17.   
  18. //3.實現代理方法. 這個方法裏面就代表下載完成了.  
  19. - (void)downloadFinshed:(NSString *)param {  
  20.     NSLog(@"%@", param);  
  21. }  
  22.   
  23. @end  


2、塊代碼傳值

 

塊代碼傳值更加簡便,且代碼更加緊湊,更方便。多線程中用塊代碼更加廣泛。

 

使用注意 :
1.當不設置block而傳入nil時,會報野指針excbadaccess. (解決:判斷一下,if(xx){..})
2.block中執行應該回主線程去更新UI,到裏面dispatch一下.
3.蘋果建議全部的塊代碼定義都不要放在頭文件中.(解決:直接在使用塊代碼的來個匿名的就OK)
*好處:能避免本身定義的塊代碼名與蘋果內置的衝突重名.
 
代碼以下:
XNUpload.h
[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import <Foundation/Foundation.h>  
  2.   
  3.   
  4. @interface XNUpload : NSObject  
  5. - (void)download:(void (^)(NSString *param))completion;  
  6. @end  


XNUpload.m

 

 

[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import "XNUpload.h"  
  2.   
  3. @implementation XNUpload  
  4. /** 
  5.  *  模擬下載完成後須要更新UI. 使用塊代碼. 
  6.  */  
  7. - (void)download:(void (^)(NSString *param))completion { //1.在參數中定義塊代碼  
  8.     NSLog(@"正在下載....");  
  9.     sleep(3.0);  
  10.     NSLog(@"下載完成!");  
  11.     //往主線程中更新UI, 須要傳遞參數. 通知主線程下載完成. (使用塊代碼)  
  12.     if (completion) {  
  13.         //這樣可讓調用者不用關心線程問題  
  14.         dispatch_async(dispatch_get_main_queue(), ^{  
  15.             completion(@"下載完成!");  //2.執行塊代碼  
  16.         });  
  17.     }  
  18. }  
  19.   
  20. @end  


XNViewController.m

 

 

[objc]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
 
  1. #import "XNViewController.h"  
  2. #import "XNUpload.h"  
  3.   
  4. @interface XNViewController ()  
  5.   
  6. @end  
  7.   
  8. @implementation XNViewController  
  9.   
  10. - (void)viewDidLoad {  
  11.     [super viewDidLoad];  
  12.     XNUpload *upload = [[XNUpload alloc] init];  
  13.   
  14.     //直接調用方法便可  
  15.     [upload download: ^(NSString *param) {  
  16.         NSLog(@"%@", [NSThread currentThread]);  
  17.         NSLog(@"%@", param);  
  18.     }];  
  19. }  
  20.   
  21. @end  


塊代碼與代理比較,用起來簡單不少,很方便。

 

 

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

相關文章
相關標籤/搜索