block的简单回调传值
2015-11-19 14:36
344 查看
由于block的火热,让我这个菜鸟也不得不多了解一下block的基本用法,虽然我之前用的是protocal代理的方式在页面之间进行的传值。但是,block的火热让我不得不来写一个demo学习下,好了废话不多说。
我所理解的block的简单用法:
首先借用大家比较熟知的一张图来解释下一般的block的样子,以及各个参数的意义。
![](http://my.csdn.net/uploads/201208/07/1344323584_7609.png)
按照调用函数的方式调用块对象变量就可以了:
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;
}
其中global时定义的一个全局变量,而在block中去调用这个变量,并且改变它是可以的,结果都是1001;
而定一个如果是一个局部变量
int local = 500;
void(^block)(void) = ^(void)
{
local++;
NSLog(@"local:%d", local);
};
block();
NSLog(@"local:%d", local);
这样在block中是不可以访问到这个变量的,会报错:
![](http://img.blog.csdn.net/20151119134827029?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
那么,如果我门想访问这个变量,并且改变它只需要在定义的时候加一个修饰符__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 = [NSString
stringWithFormat:@"点击 %d次",num];
[self.navigationController
popViewControllerAnimated: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 = [[BlockTestViewController
alloc]
init];
blockTest.callBack=^(NSString *str){
[weakSelf.button
setTitle:str forState:UIControlStateNormal];
};
[self.navigationController
pushViewController: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 {
[super
viewDidLoad];
UIButton *testButton = [UIButton
buttonWithType:UIButtonTypeCustom];
testButton.frame =
CGRectMake(100,
400, 100,
40);
[testButton setTitle:@"click"
forState:UIControlStateNormal];
[testButton addTarget:self
action:@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.navigationController
pushViewController: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 {
[super
viewDidLoad];
UIButton *testButton = [UIButton
buttonWithType:UIButtonTypeCustom];
testButton.frame =
CGRectMake(100,
400, 100,
40);
[testButton setTitle:@"click"
forState:UIControlStateNormal];
[testButton addTarget:self
action:@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++;
}
}
我所理解的block的简单用法:
首先借用大家比较熟知的一张图来解释下一般的block的样子,以及各个参数的意义。
![](http://my.csdn.net/uploads/201208/07/1344323584_7609.png)
按照调用函数的方式调用块对象变量就可以了:
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;
}
其中global时定义的一个全局变量,而在block中去调用这个变量,并且改变它是可以的,结果都是1001;
而定一个如果是一个局部变量
int local = 500;
void(^block)(void) = ^(void)
{
local++;
NSLog(@"local:%d", local);
};
block();
NSLog(@"local:%d", local);
这样在block中是不可以访问到这个变量的,会报错:
那么,如果我门想访问这个变量,并且改变它只需要在定义的时候加一个修饰符__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 = [NSString
stringWithFormat:@"点击 %d次",num];
[self.navigationController
popViewControllerAnimated: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 = [[BlockTestViewController
alloc]
init];
blockTest.callBack=^(NSString *str){
[weakSelf.button
setTitle:str forState:UIControlStateNormal];
};
[self.navigationController
pushViewController: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 {
[super
viewDidLoad];
UIButton *testButton = [UIButton
buttonWithType:UIButtonTypeCustom];
testButton.frame =
CGRectMake(100,
400, 100,
40);
[testButton setTitle:@"click"
forState:UIControlStateNormal];
[testButton addTarget:self
action:@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.navigationController
pushViewController: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 {
[super
viewDidLoad];
UIButton *testButton = [UIButton
buttonWithType:UIButtonTypeCustom];
testButton.frame =
CGRectMake(100,
400, 100,
40);
[testButton setTitle:@"click"
forState:UIControlStateNormal];
[testButton addTarget:self
action:@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++;
}
}
相关文章推荐
- Servlet:JSP理解
- linker command failed with exit code 1
- About ANR and OOM
- Asp.Net HttpApplication请求管道与Session(二)
- iOS中 XMPP即时通讯实现的主要步骤
- php保存base64数据
- android四大组件之Service 播放音乐
- web性能优化
- 连续ping IP地址 shell脚本【来自《鸟哥linux的私房菜》】
- 祝兄弟们旗开得胜—兄弟连IT教育
- 【Android】长按连续触发事件的实现方法
- Android编程实现仿心跳动画效果的方法
- Node初学者入门,一本全面的NodeJS教程(推荐阅读)
- Android实现启动页停留几秒然后自动跳转到App首页的方法
- android录制声音写入文件
- java获取访问者的IP
- 怎么修改docker images的存储目录
- 1025 PAT Ranking
- 关于android应用的toolbar(actionbar)不能填满布局解决
- azure注册码