由于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, const char * argv[])
- {
- @autoreleasepool {
- void(^block)(void) = ^(void)
- {
- global++;
- NSLog(@"global:%d", global);
- };
- 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的函数typedef void (^clickButtonCallBack)(NSString *str);让它可以传递一个字符串类型的参数,没有返回值。然后为类定义个参数,其中clickButtonCallBack作为一种类型来定义callBack变量。 一开始也不习惯这种写法,但是,只要牢记block的基本样子,还是可以对照着写出来这个回调函数的typedef void (^clickButtonCallBack)(NSString *str)然后我们回到页面b的.m文件中,在点击事件中:
- (void)clickButton{
static int num =0;
NSString *s = [NSStringstringWithFormat:@"点击 %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 = [UIButtonbuttonWithType:UIButtonTypeCustom];
testButton.frame =CGRectMake(100,400, 100, 40);
[testButton setTitle:@"click"forState:UIControlStateNormal];
[testButton addTarget:selfaction:@selector(clickButton)forControlEvents:UIControlEventTouchUpInside];
_button = testButton;
testButton.backgroundColor = [UIColorredColor];
[self.viewaddSubview:testButton];
// Do any additional setup after loading the view.
}
- (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];
}
页面b中:
.h
#import <UIKit/UIKit.h>
typedefvoid (^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 = [UIButtonbuttonWithType:UIButtonTypeCustom];
testButton.frame =CGRectMake(100,400, 100, 40);
[testButton setTitle:@"click"forState:UIControlStateNormal];
[testButton addTarget:selfaction:@selector(clickButton)forControlEvents:UIControlEventTouchUpInside];
testButton.backgroundColor = [UIColorredColor];
_testButton = testButton;
[self.viewaddSubview:testButton];
// Do any additional setup after loading the view.
}
- (void)clickButton{
static int num = 0;
NSString *s = [NSStringstringWithFormat:@"点击 %d次",num];
[self.navigationControllerpopViewControllerAnimated:YES];
if(self.callBack){
self.callBack(s);
num++;
}
}