从一开始学习Block就一直被我视为很高大上的东西,尤其是这种特殊的形式,很炫酷也很好用。最早接触block大概是AFnetworking2.0版本封装好的方法,当时只知道怎么用,其实对于block还是一点不了解。之前写的一个传值用的是代理,今天无聊把他改成了block传值,就记下来吧。
Block我认为就是相当于C语言中声明了一个方法,然后带上参数(当然也可以不带参数),之所以能够传值,就是你在使用block时,参数可以传递。
比如说我们如果从A界面跳转到B界面,并向B传值,那么很简单,直接KVC就可以,但是如果从B返回A呢?或者说从把一个类里的数据传送到另一个类里面,而且2者直接并没有跳转关系呢。这时候就可以用Block来实现。
先简单介绍一下Block
block的形式如下: 类型(^名称)(参数){} ^符号就是block的标识;
#import "ViewController.h"
void (^myBlock)(int, int);
int (^myBlock1)(int a, int b);
void (^myBlock2)();
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*block就像C语言里面声明方法,只是必须要(^方法名)这个格式来说明它是block*/
/*block使用时,就像C一样必须按照方法名(参数)的形式,不然是不会*/
myBlock=^(int a,int b){
NSLog(@"myBlock=%d" ,a+b);
};
myBlock(10,20);
myBlock1=^(int a, int b){
return a+b;
};
NSLog(@"myBlock1=%d",myBlock1(2,3));
/*哪怕是不需要参数的,必须调用该方法才会执行block里面的代码*/
myBlock2=^{
NSLog(@"Block 真好用");
};
myBlock2();
}
block强大一点在于它还可以作为参数来使用,比如用typedef来自定义你想要的block格式
typedef void(^myBlock3)();
@interface ViewController ()
@property (nonatomic, strong) myBlock3 myblock3;
或者直接
@property (nonatomic, strong) void (^myBlock4)(NSString *,NSString *);
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_myBlock4=^(NSString *str1, NSString *str2){
NSLog(@"%@",[str1 stringByAppendingString:str2]);
};
_myBlock4(@"我爱",@"欧洲杯");
然后就是最常用的传值啦,就拿刚改的这个里面最简单的那个,如下:
由于最上面的scroll那一栏是自定义的一个view,于是在点击scroll跳转到相应的页面需要将相应的数据传递给视图控制器。之前我用delegate做,比较麻烦,用block就方便很多。
/*首先还是声明好block,把数据model作为参数传入*/
#import <UIKit/UIKit.h>
#import "TopScrollitemModel.h"
typedef void (^trans)(<span class="s1" style="font-family: Arial, Helvetica, sans-serif;">NSInteger</span><span class="s2" style="font-family: Arial, Helvetica, sans-serif;"> i)</span>;
@interface TopScroll : UIView<UIScrollViewDelegate,UIGestureRecognizerDelegate>
@property (nonatomic, strong) trans mytrans;
在.m的实现方法中,为scroll添加点击事件
@implementation TopScroll
-(void)ClickWithTag:(NSInteger)tag{
//将当前的页数传递过去
_mytrans(self.pagecontrol.currentPage);
// [self.delegate ClickWithTag:self.pagecontrol.currentPage];
}
然后在控制器中获取相应的数据
UINib * nib = [UINib nibWithNibName:@"TopScroll" bundle:nil];
NSArray * array = [nib instantiateWithOwner:self options:nil];
TopScroll *topScroll= [array firstObject];
topScroll.delegate=self;
topScroll.frame = CGRectMake(0, 0, SCREEN_WIDTH, 120);
[topScroll setData:self.topContentModel];
//每次点击时都会调用myTrans这个block,就会把参数传递过来。
//然后实现下面的方法,实现相应的跳转。
topScroll.mytrans=^(NSInteger i){
WebViewController *webView=[[WebViewController alloc]init];
TopScrollitemModel *model=[[TopScrollitemModel alloc]init];
model=self.topContentModel.contents[i];
webView.Url=model.source;
[webView setHidesBottomBarWhenPushed:YES];
[self.navigationController pushViewController:webView animated:YES];
};
[self.HomeSrcoll addSubview:topScroll];
}
或者我们再看一个更通俗的例子,也是大多数将block会讲到的例子。
首先在A界面中,设置一个label和一个button,B界面设置一个textfiled和一个button, A界面点击button跳转到B,Btextfiled输入内容,点button回到A界面,并将数据传递回来,显示在label中。
A中:
/*在a中写好block方法的实现过程如下*/
- (IBAction)tranAction:(id)sender {
UIStoryboard *main=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
BViewController *b=[main instantiateViewControllerWithIdentifier:@"B"];
b.transStr=^(NSString *str){
_ALabel.text=str;
};
[b setTitle:@"B"];
[self.navigationController pushViewController:b animated:YES];
}
B:中
/*B中button点击中实现block*/
/*之后block就会按照A中的实现方法来实现,并且还会用到B传过去的参数*/
- (IBAction)BackAction:(id)sender {
if (_tf.text.length!=0) {
_transStr(_tf.text);
}
[self.navigationController popViewControllerAnimated:YES];
}