block的簡單回撥傳值
由於block的火熱,讓我這個菜鳥也不得不多瞭解一下block的基本用法,雖然我之前用的是protocal代理的方式在頁面之間進行的傳值。但是,block的火熱讓我不得不來寫一個demo學習下,好了廢話不多說。
我所理解的block的簡單用法:
首先借用大家比較熟知的一張圖來解釋下一般的block的樣子,以及各個引數的意義。
按照呼叫函式的方式呼叫塊物件變數就可以了:
int result = myBlock(4);
result是 28
。。。。。。。。。
當然對上圖我的理解是,block定義的一種方法,這個方法需要傳入一個int型別的引數,返回值也是一個int型別的數值。而myBlock就是函式的名字,我們在c語言中呼叫一個函式的時候,就是myBlock(4);這樣呼叫,而且用一個int型別的result來接收返回值。
正如c語言中的函式,如果你定義了一個函式,而沒有去呼叫這個函式,那麼這個函式就不會執行(雖然這裡說的不是特別對,但是可以這樣理解)。所以想讓函式執行,那麼我們需要在main函式中去呼叫我們定義的這個函式。
再看下邊的例子:
- int global = 1000;
- int main(int argc, constchar * argv[])
- {
- @autoreleasepool {
- void(^block)(void) = ^(void)
- {
- global++;
-
NSLog(@"global:%d"
- };
- block();
- NSLog(@"global:%d", global);
- }
- return 0;
- }
而定一個如果是一個區域性變數
- int local = 500;
- void(^block)(void) = ^(void)
- {
- local++;
- NSLog(@"local:%d", local);
- };
-
block();
- NSLog(@"local:%d", local);
那麼,如果我門想訪問這個變數,並且改變它只需要在定義的時候加一個修飾符__block,然後我們就可以訪問並且改變它了。
說了這麼多無非想引入我要說的block的回撥傳值:
在兩個頁面間,當一個頁面A和一個頁面B之間,如果我想的是a中有一個button,點選這個button進入b。但是在b中有一個按鈕,只有我點選b的按鈕時,並且b會傳值給a中的button來顯示。
由於block資料型別的語法會降低整個程式碼的閱讀性,所以常使用typedef來定義block型別。
開始,我搞不懂在哪個裡邊定義block的回撥函式,所以只能死記了。哪個頁面要傳值,哪個頁面來定義這個block的回撥函式。
首先,我知道頁面a中button顯示的東西是頁面b點選按鈕時傳遞過來的,所以按照我記住的就是由頁面b來定義這個block回撥函式。
所以程式碼如下:
#import <UIKit/UIKit.h>
typedef void (^clickButtonCallBack)(NSString *str);
@interface BlockTestViewController : UIViewController
@property (copy, nonatomic) clickButtonCallBack callBack;
@end
我在b頁面定義一個回撥函式,也就是callBack的setter函式。首先定義個block的函式typedefvoid (^clickButtonCallBack)(NSString *str);讓它可以傳遞一個字串型別的引數,沒有返回值。然後為類定義個引數,其中clickButtonCallBack 作為一種型別來定義callBack變數。 一開始也不習慣這種寫法,但是,只要牢記block的基本樣子,還是可以對照著寫出來這個回撥函式的typedefvoid (^clickButtonCallBack)(NSString *str) 然後我們回到頁面b的.m檔案中,在點選事件中:- (void)clickButton{
static int num = 0;
NSString *s = [NSString stringWithFormat:@"點選 %d次",num];
[self.navigationControllerpopViewControllerAnimated:YES];
if(self.callBack){
self.callBack(s);
num++;
}
}
我做了簡單的處理,定義個num來記錄我點選的次數,其實傳遞的字串就是s,也就是我點選的次數形成的字串頁面b是由頁面a push進來的,我們現在看頁面a的.m中我做的處理,同樣我在頁面a中有一個按鈕,點選按鈕的事件是:
- (void)clickButton{
__weak typeof(self) weakSelf = self;
BlockTestViewController *blockTest = [[BlockTestViewControlleralloc] init];
blockTest.callBack=^(NSString *str){
[weakSelf.button setTitle:str forState:UIControlStateNormal];
};
[self.navigationControllerpushViewController:blockTest animated:YES];
}
其中,BlockTestViewController 便是我說的頁面b,blockTest.callBack=^(NSString *str){
[weakSelf.button setTitle:str forState:UIControlStateNormal];
};
這裡就是我呼叫block的回撥函式時觸發的事件。str便是頁面b傳過來的引數
經驗證傳值成功。下邊是全部程式碼:
頁面a中:
.h
#import <UIKit/UIKit.h>
@interface BlockNextViewController : UIViewController
@end
.m#import "BlockNextViewController.h"
#import "BlockTestViewController.h"
@interface BlockNextViewController ()
@property (nonatomic, weak) UIButton *button;
@end
@implementation BlockNextViewController
- (void)viewDidLoad {
[superviewDidLoad];
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeCustom];
testButton.frame = CGRectMake(100, 400, 100, 40);
[testButton setTitle:@"click"forState:UIControlStateNormal];
[testButton addTarget:selfaction:@selector(clickButton) forControlEvents:UIControlEventTouchUpInside];
_button = testButton;
testButton.backgroundColor = [UIColor redColor];
[self.view addSubview:testButton];
// Do any additional setup after loading the view.
}
- (void)clickButton{
__weak typeof(self) weakSelf = self;
BlockTestViewController *blockTest = [[BlockTestViewController alloc] init];
blockTest.callBack=^(NSString *str){
[weakSelf.button setTitle:str forState:UIControlStateNormal];
};
[self.navigationControllerpushViewController:blockTest animated:YES];
}
頁面b中:
.h
#import <UIKit/UIKit.h>
typedef void (^clickButtonCallBack)(NSString *str);
@interface BlockTestViewController : UIViewController
@property (copy, nonatomic) clickButtonCallBack callBack;
@end
.m
#import "BlockTestViewController.h"
@interface BlockTestViewController ()
@property (nonatomic, weak) UIButton *testButton;
@end
@implementation BlockTestViewController
- (void)viewDidLoad {
[superviewDidLoad];
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeCustom];
testButton.frame = CGRectMake(100, 400, 100, 40);
[testButton setTitle:@"click"forState:UIControlStateNormal];
[testButton addTarget:selfaction:@selector(clickButton) forControlEvents:UIControlEventTouchUpInside];
testButton.backgroundColor = [UIColor redColor];
_testButton = testButton;
[self.view addSubview:testButton];
// Do any additional setup after loading the view.
}
- (void)clickButton{
static int num = 0;
NSString *s = [NSString stringWithFormat:@"點選 %d次",num];
[self.navigationController popViewControllerAnimated:YES];
if(self.callBack){
self.callBack(s);
num++;
}
}