主線程與子線程經常需要進行資料的傳遞,不同的類之間,不同的控制器之間都需要。
而且經常需要監聽一個動作的完成,而後才去做相應事件。(代理是一對一的關系)。
一、代理傳值
代理是一種設計模式。iOS中用的非常多。可以通過自定義代理來進行傳值。
參見我的這篇文章 http://blog.csdn.net/xn4545945/article/details/31036523
在iOS中,委托方與被委托方都要實作3個步驟。(見代碼注釋)
下面代碼:模拟下載下傳完成後需要更新UI. 用代理來傳值.
XNUpload.h
[objc] view plain copy
- #import <Foundation/Foundation.h>
- //1.定義代理協定
- @protocol XNUploadDelegate <NSObject>
- - (void)downloadFinshed:(NSString *)param;
- @end
- @interface XNUpload : NSObject
- //2.定義代理屬性
- @property (nonatomic, assign) id <XNUploadDelegate> delegate;
- -(void)download;
- @end
XNUpload.m
[objc] view plain copy
- #import "XNUpload.h"
- @implementation XNUpload
- - (void)download {
- NSLog(@"正在下載下傳....");
- sleep(3.0);
- NSLog(@"下載下傳完成!");
- //3.往主線程中更新UI, 需要傳遞參數. 通知主線程下載下傳完成. (調用代理方法)
- [self.delegate downloadFinshed:@"下載下傳完成啦!"];
- }
- @end
XNViewController.m
[objc] view plain copy
- #import "XNViewController.h"
- #import "XNUpload.h"
- @interface XNViewController () <XNUploadDelegate> //1. 遵守代理協定
- @end
- @implementation XNViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- XNUpload *upload = [[XNUpload alloc] init];
- [upload download]; //下載下傳了
- //2. 設定代理
- upload.delegate = self;
- }
- //3.實作代理方法. 這個方法裡面就表明下載下傳完成了.
- - (void)downloadFinshed:(NSString *)param {
- NSLog(@"%@", param);
- }
- @end
二、塊代碼傳值
塊代碼傳值更加簡便,且代碼更加緊湊,更友善。多線程中用塊代碼更加普遍。
使用注意 : 1. 當不設定 block 而 傳入 nil 時 , 會報野指針 exc bad access. ( 解決 : 判斷一下 , if(xx){ .. }) 2. block 中 執行應該回主線程 去更新 UI, 到裡面 dispatch 一下 . 3 . 蘋果建議所有的 塊代碼定義 都 不要 放在 頭檔案 中 . ( 解決 : 直接在使用塊代碼的 來個匿名的 就 OK) * 好處 : 能 避免 自己定義的塊代碼名與蘋果内置的 沖突重名 .
代碼如下: XNUpload.h
[objc] view plain copy
- #import <Foundation/Foundation.h>
- @interface XNUpload : NSObject
- - (void)download:(void (^)(NSString *param))completion;
- @end
XNUpload.m
[objc] view plain copy
- #import "XNUpload.h"
- @implementation XNUpload
- - (void)download:(void (^)(NSString *param))completion { //1.在參數中定義塊代碼
- NSLog(@"正在下載下傳....");
- sleep(3.0);
- NSLog(@"下載下傳完成!");
- //往主線程中更新UI, 需要傳遞參數. 通知主線程下載下傳完成. (使用塊代碼)
- if (completion) {
- //這樣可以讓調用者不用關心線程問題
- dispatch_async(dispatch_get_main_queue(), ^{
- completion(@"下載下傳完成!"); //2.執行塊代碼
- });
- }
- }
- @end
XNViewController.m
[objc] view plain copy
- #import "XNViewController.h"
- #import "XNUpload.h"
- @interface XNViewController ()
- @end
- @implementation XNViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- XNUpload *upload = [[XNUpload alloc] init];
- //直接調用方法即可
- [upload download: ^(NSString *param) {
- NSLog(@"%@", [NSThread currentThread]);
- NSLog(@"%@", param);
- }];
- }
- @end
塊代碼與代理比較,用起來簡單很多,很友善。
轉載請注明出處:http://blog.csdn.net/xn4545945