IOS开发学习记录之Block的使用。

来源:互联网 发布:许朝军 知乎 编辑:程序博客网 时间:2024/05/17 23:00

从一开始学习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];}


之所以能传值是因为:

1,block作为一个类的属性,可以被另一个类调用,或者说你可以把他当成一个实例方法被另一个类调用。 

2, block的方法实现你可以写在另一个类中,比如上面的控制器中,无论你写在哪,只要再次激活了 myBlock(int, int);这样的方法,就会回调它的实现方法,从而实现值得回调和操作的响应。

一句话来概述就是,无论你的block具体实现写在哪里,只要调用了这个block,就会执行它的具体实现过程,并且调用时的参数也会被使用,因此可以回调。

0 0
原创粉丝点击