文档章节

block的基本语法和应用

云飞扬v5
 云飞扬v5
发布于 2016/05/21 12:00
字数 1797
阅读 45
收藏 2
点赞 2
评论 0

代码片段block基本语法

block就是一段语句组成的代码段,可以认为整个block里面就是一句代码,可以有参数和返回值。可以看看下面几种常见的情况。

不带参数无返回值

这里是打印系统时间的一个例子

   //无参数,无返回值的block
    void (^logTime)(void)=^{
        NSLog(@"time is ==%@",[NSDate date]);
    };
    
    //调用block
    logTime();
    
    /*
     print time is ==2016-05-21 02:13:08 +0000

     
     */

不带参数有返回值

获取当前时间的例子

  //不带参数,有返回值
    NSDate* (^getNowDate)(void)=^{
        return [NSDate date];
    };
    
    NSDate *nowDate=getNowDate();
    NSLog(@"nowDate==%@",nowDate);
//    print nowDate==2016-05-21 02:43:24 +0000

 

带参数无返回值

打印传入的参数

   //有参数,无返回值的block
    void (^logInput)(NSString *input)=^(NSString *input){
        NSLog(@"input==%@",input);
        
    };
    //调用logInput
    logInput(@"abc");
  
    // print input==abc

 

 

带参数有返回值

单个参数

对传入参数乘以7

    //有参数,有返回值
    int (^multiplierBy7)(int)=^(int multiplier){
        return multiplier*7;
    };
    int result= multiplierBy7(3);
    NSLog(@"result==%i",result);
    // print result==21

多个参数

传入4个参数的情况,计算立方体的体积

    //有多个参数,有返回值的block
    double (^calculateCubicVolume)(double ,double ,double ,NSString *)=^(double length,double width,double height,NSString *cubicName){
        double volume=length*width*height;
        NSLog(@"cubic name==%@",cubicName);
        return volume;
    };
    //调用block
    double volume1=calculateCubicVolume(1,2,3,@"cubic demo 1");
    NSLog(@"volume==%f",volume1);
    /*
    print
        cubic name==cubic demo 1
        volume==6.000000
     */

 

作为函数的参数

 

定义函数

void testFunction(int i1,void(^actionBlock)(int)){
    if (actionBlock) {
        actionBlock(i1);
        NSLog(@"in function i1==%i",i1);
    }
}

 

调用函数

   testFunction(1024, ^(int i2) {
     
        NSLog(@"use function i2 ==%i",i2);
    });
    /*
    print use function i2 ==1024
    in function i1==1024
     */

作为方法的参数

__block BOOL found = NO;
NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];
NSString *string = @"gamma";
 
[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
    if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {
        *stop = YES;
        found = YES;
    }
}];
 
// At this point, found == YES

 

 

作为属性

直接声明作为属性的block

  
//声明block类型的属性

#import "HBTestBlock.h"

@interface HBTestBlock ()
@property(nonatomic, copy) UIView *(^viewGetter)(NSString *imageName); //注意其返回类型为UIView *

@end

//在另一个类中调用

 HBTestBlock *objPropertyBlockObj = [[HBTestBlock alloc] init];
    objPropertyBlockObj.viewGetter = ^(NSString *imageName){
//        return [[UIView alloc] init]; //特别注意此处,若对象不匹配,则会报错,设置为nil也会报错。
        return [self currentView];
    };


    objPropertyBlockObj.viewGetter(@"hello"); //实际执行block

 

通过typedef 简化定义的过程


#import "ViewController.h"


typedef int(^compareBlock)(int a, int b);


@interface ViewController ()
//声明属性的block
//使用简化方式的定义
@property (nonatomic,copy) compareBlock compare1;

//使用基本方式进行定义
@property (nonatomic,copy) int (^compare2)(int a,int b);

//void类型block 属性的定义
@property (nonatomic,copy) void (^networkFailure)(NSError *error);

//对象类型的block属性的定义
@property (nonatomic,copy) UIView *(^getAView)(NSString *imageName);



@implementation ViewController

-(void)viewDidLoad{
 //赋值属性的block
    self.compare1=^(int a,int b){
        NSLog(@"compare1 a==%d,b==%d,result==%@",a,b,a>b?@"a>b":@"a<=b");
        return a>b;
        
    };

    self.compare2=^(int a,int b){
        NSLog(@"compare2 a==%d,b==%d,result==%@",a,b,a>b?@"a>b":@"a<=b");
        return a>b;
        
    };

 //执行属性的block,这里没有接收返回值
    
    if (self.compare1) {
         self.compare1(5,6);
    }
    
    if (self.compare2) {
         self.compare2(5,6);
    }




}


@end


/*
print 打印结果
  compare1 a==5,b==6,result==a<=b
  compare2 a==5,b==6,result==a<=b

*/

 

 

避免循环引用

 

block的应用

封装网络请求

对某些经常变化的部分代码做封装

 

因为block的调用和实现是分开的,所以可以处理一些变化的代码。比如数组中做筛选的条件就可以是一个bool返回类型的block,或者对数组进行排序的场景中,返回2个元素的顺序的代码用block实现,这样就有了很大的灵活性。

下面就举一个数字排序的例子

/**
 *  排序的方法
 *
 *  @param numberArray 输入的数组
 *  @param comparator  比较2个数字大小的block
 *
 *  @return 返回排序后的数组
 */
-(NSArray *)sortNumberWithNumberArray:(NSArray *)numberArray
                      comparatorBlock:(BOOL(^)(NSNumber *,NSNumber *))comparator{
    /**
     *  存放排序前的数组
     */
    NSMutableArray *beforeSort=numberArray.mutableCopy;
    /**
     *  存放排序后的数组
     */
    NSMutableArray *afterSort=[NSMutableArray array];
    //每次循环确定第j+1个最大的数字
    for (int j=0; j<numberArray.count; j++) {
        
        //假设第一个元素就是最大的结果
        NSNumber *maxNumber=[beforeSort firstObject];
        
        
        for (int i=0; i<beforeSort.count; i++) {
            NSNumber *numberIndex=beforeSort[i];
           //用比较大小的block进行比较,其实这里并不知道block的内容,只是确定了block的返回值和参数。后续调用的时候,可以进行多种条件的实现
            BOOL largerThanPreviousMax= comparator(numberIndex,maxNumber);
            //如果遇到一个比之前最大数字还大的数字,那就把当前最大的数字放在maxNumber里面
            if (largerThanPreviousMax==YES) {
                maxNumber=numberIndex.copy;
                
            }
            
        }
        
        //将取到的第j+1个数移出排序前数组,放入排序后数组
        [beforeSort removeObject:maxNumber];
        [afterSort addObject:maxNumber];
        
    }

    return afterSort.copy;

}

 

调用的时候,定义了2个不同的场景,按照数字的整数大小排列,以及按照绝对值大小进行排序

 //排序前的数组
    NSArray *array=@[@1,@(-2),@3,@(-9),@4,@8];
    //根据数值的大小进行排序
    BOOL (^comparator)(NSNumber*,NSNumber*)=^(NSNumber *num1,NSNumber *num2){
        BOOL result=[num1 integerValue]>[num2 integerValue];
        return result;
    };
    NSArray *resultArray=[self sortNumberWithNumberArray:array comparatorBlock:comparator];
    
    
    
    NSLog(@"resultArray%@",resultArray);
    /*
    print   resultArray(
                        8,
                        4,
                        3,
                        1,
                        "-2",
                        "-9"
                        )
     
     */

    //根据绝对值的大小进行排序
    BOOL (^absoluteSortComparator)(NSNumber *,NSNumber *)=^(NSNumber *num1,NSNumber *num2){
    
        BOOL result=fabs([num1 doubleValue])>fabs([num2 doubleValue]);
        return result;
    
    };
    NSArray *absoluteSortArray=[self sortNumberWithNumberArray:array comparatorBlock:absoluteSortComparator];
    NSLog(@"absoluteSortArray%@",absoluteSortArray);
    
/*
    print  absoluteSortArray(
                             "-9",
                             8,
                             4,
                             3,
                             "-2",
                             1
                             )
 */

 

block传值的应用场景介绍

有2个控制器,A控制器显示一个问题,你最喜欢的数字是哪个?点了选择以后就跳转到B控制器,在B控制器有一个列表,可以供用户选择。需求就是在B中选择了以后,A中做出相应的修改。

 

接下来就上代码了

首先是第一个页面

.h 

#import <UIKit/UIKit.h>

@interface FavouriteNumberViewController : UIViewController

@end

 

.m

//
//  FavouriteNumberViewController.m
//  BlockPassValue
//

//

#import "FavouriteNumberViewController.h"

#import "ChoosingFavouriteNumberViewController.h"

@interface FavouriteNumberViewController ()

@property (nonatomic,weak) UILabel *favouriteNumberLabel;



@end

@implementation FavouriteNumberViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UILabel *favouriteNumberLabel=[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 100)];
    favouriteNumberLabel.font=[UIFont systemFontOfSize:13.0];
    
    favouriteNumberLabel.backgroundColor=[UIColor greenColor];
    
    [self.view addSubview:favouriteNumberLabel];
    self.favouriteNumberLabel=favouriteNumberLabel;
    
    UIButton *pickNumberButton=[[UIButton alloc]initWithFrame:CGRectMake(100, 200, 200, 100)];
    
    [pickNumberButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [pickNumberButton setTitle:@"点击选择数字" forState:UIControlStateNormal];
    [pickNumberButton addTarget:self action:@selector(pickupNumber) forControlEvents:UIControlEventTouchUpInside];
    pickNumberButton.backgroundColor=[UIColor orangeColor];
    
    [self.view addSubview:pickNumberButton];
    
    
    
    // Do any additional setup after loading the view.
}


-(void)pickupNumber{

    ChoosingFavouriteNumberViewController *choosingNumberVC=[[ChoosingFavouriteNumberViewController alloc]init];
    __weak typeof (self) weakSelf=self;
    choosingNumberVC.chooseNumberBlock=^(NSString *number){
        weakSelf.favouriteNumberLabel.text=[NSString stringWithFormat:@"最喜欢的数字是%@",number];
       
        
    };
    
    [self.navigationController pushViewController:choosingNumberVC animated:YES];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

 

.h

#import <UIKit/UIKit.h>

typedef  void (^ChooseNumberBlock) (NSString *number) ;

@interface ChoosingFavouriteNumberViewController : UIViewController

@property (nonatomic,copy) ChooseNumberBlock chooseNumberBlock;

@end

 

 

.m

//
//  ChoosingFavouriteNumberViewController.m
//  BlockPassValue
//

//

#import "ChoosingFavouriteNumberViewController.h"

@interface ChoosingFavouriteNumberViewController ()
<UITableViewDataSource,UITableViewDelegate>

@property (nonatomic,weak) UITableView *tableView;

@property (nonatomic,strong) NSArray *numberArray;

@end

@implementation ChoosingFavouriteNumberViewController
#pragma mark - vc life cycle
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title=@"请选择你喜欢的数字";
    UITableView *tableView=[[UITableView alloc]init];
    tableView.delegate=self;
    tableView.dataSource=self;
    [self.view addSubview:tableView];
    
    tableView.frame=self.view.bounds;
    self.tableView=tableView;
    
    self.view.backgroundColor=[UIColor whiteColor];
    

    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - data getter

-(NSArray *)numberArray{

    if (!_numberArray) {
       
        NSMutableArray *numberArray=[NSMutableArray array];
        for (int i=0; i<10; i++) {
            [numberArray addObject:[NSString stringWithFormat:@"%i",i]];
        }
        _numberArray=numberArray.copy;
    }
    return _numberArray;

}
#pragma mark -table view datasource

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return self.numberArray.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifier=@"cellIdentifier";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(!cell){
    
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    cell.textLabel.text=self.numberArray[indexPath.row];
    
    return cell;

}

#pragma mark - table view delegate

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

//调用了之前定义的block内容
    if (self.chooseNumberBlock) {
        NSString *selectedNumber=self.numberArray[indexPath.row];
        self.chooseNumberBlock(selectedNumber);
    }
    [self.navigationController popViewControllerAnimated:YES];
    

}


@end

 

 

 

 

 

 

 

 

block中的变量的对应管理

局部变量

全局变量

__block修饰的变量

 

 

 

 

参考资料

重要经验五:block作为属性的注意事项

http://blog.csdn.net/lvmaker/article/details/25468485

 

 

© 著作权归作者所有

共有 人打赏支持
云飞扬v5
粉丝 11
博文 105
码字总数 67465
作品 0
金华
【javac添加python 列表特性10】为Block添加返回值

前面几篇提到的一些特性,都是通过把特殊的新语法,翻译成java可以支持的语法来实现的。javac编译一个文件的过程为:(参见javac编译文件过程) Scanner->Parser->Annotation(optional)->Ent...

guoliang
2013/01/08
0
0
(一)Block的实质初探

相关文章 (一)Block的实质初探 (二)Block之存储域 NSConcreteStackBlock,NSConcreteGlobalBlock,NSConcreteMallocBlock (三)Block之截获变量和对象 (四)Block之 _block修饰符及其存...

madaoCN
2017/10/21
0
0
01 - Object-C入门

Object-C简介 在C语言的基础之上,增加了一层最小的面向对象语法 完全兼容C语言 oc代码中可以混合使用C语言和C++代码 oc可以用来开发MAC OS X平台和 ios平台的应用程序 基本语法 关键字 基本...

口十耳
2015/12/22
59
0
Pug+Stylus+Bootstrap入门

本文说明 博主最近在学习Express.js,里面涉及到Pug,Stylus和Bootstrap的使用。为了使文章主题专一,故而把有关这三者的基本知识点另外写成本文。 本文在写作过程中主要参阅了下面这些资料:...

桥头堡2015
2016/04/13
963
0
block语法

一、block应用范围 1、动画的转场 2、网络的事件处理 3、两个对象或者多个对象之间的通讯 4、多线程的处理 (从iOS4.0开始就应用得非常广泛) 二、Block block和C语言中的函数(函数指针)有...

Cy_Star
2017/11/22
0
0
Block作为属性、方法参数、返回值

简介: 首先来概述一下,Block对象提供了一个 特别的(ad hoc)函数,这个函数是使用C和C派生语言(如Objective-C和C++)来创建的一个表达式,Block对象在其他语言和环境中有时候可以理解为一...

吃粑粑的毕教授
2017/10/07
0
0
学习之路/CSS扩展语言SASS

CSS扩展语言SASS学习 欢迎阅读我所有的学习之路系列文章: 学习之路系类文章目录 介绍 SASS官网: Sass is the most mature, stable, and powerful professional grade CSS extension langua...

DennisGuo
2015/11/23
92
2
overflow --百度百科

overflow CSS属性 overflow 为CSS中设置当对象的内容超过其指定高度及宽度时如何管理内容的属性。 基本特性 初始值: visible 适用于: block-level and replaced elements 继承性: 无 百分...

折冲樽俎
2011/05/09
0
0
Objective-C中的Block

技术是需要沉淀的。接触iOS开发也有大半年时间了,从一开始的纯白到现在自我感觉略懂一点,其实进步是明显的。无数牛人表示技术博是完成菜鸟到高手蜕变的途径之一,虽然这个博客并非是为技术...

Karlon
2014/07/12
0
5
TCL脚本语言详解

语言简介 TCL是一种很通用的脚本语言,功能强大。最早称为“工具命令语言”"Tool Command Language",但是目前已经不是这个含义,不过我们仍然称呼它TCL,发音为"tickle”。TCL经常被用于快速...

zengxiantao1994
2017/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

217. Contains Duplicate - LeetCode

Question 217. Contains Duplicate Solution 题目大意:判断数组中是否有重复元素 思路:构造一个set,不重复就加进去,重复返回true,如果数据量大的话,可以用布隆过滤器 Java实现: publ...

yysue
1分钟前
0
0
istio 处理失败

Envoy提供了一套开箱即用的选择加入故障恢复功能,可以通过应用程序中的服务进行利用。功能包括: 超时 具有超时预算和重试之间的可变抖动的有界重试 限制并发连接数和对上游服务的请求 对负...

xiaomin0322
2分钟前
0
0
eclipse解决git冲突举例

本地修改了两个文件,提交时提示有冲突,想来应该是没有从远程仓库下载最新代码导致的。通过右击项目 -> Team -> Sychronized WorkSpace,比较本地仓库和远程仓库的异同:   此时没有更好的...

Code辉
11分钟前
0
0
运行.jar后缀的文件

前提必须安装了jdk,正确配置环境变量。 在dos窗口执行以下命令即可。 java -jar C:\Users\10492\Desktop\turn.jar

haha360
14分钟前
0
0
Java程序员如何做代码压力测试?【JWordPress前台项目实战】

代码 pom.xml文件引入包 <dependency><groupId>com.taobao.stresstester</groupId><artifactId>stresstester</artifactId><version>1.0</version></dependency> 编写测试代码 /**......

迷你芊宝宝
18分钟前
0
0
面试宝典-什么是缓存穿透?

缓存穿透是说收到了一个请求,但是该请求缓存里没有,只能去数据库里查询,然后放进缓存。 这里面有两个风险,一个是同时有好多请求访问同一个数据,然后业务系统把这些请求全发到了数据库;...

suyain
24分钟前
0
0
vue基础知识练习2

一、发送AJAX请求 <div id="demo1"><button @click="send">发送AJAX请求</button><button @click="sendGet">GET方式发送AJAX请求</button><button @click="sendPost">POST方式发送A......

一个yuanbeth
26分钟前
0
0
Xamarin Essentials教程磁力计Magnetometer

Xamarin Essentials教程磁力计Magnetometer 磁力计也叫地磁、磁感器,可用于测试磁场强度和方向。在手持设备中,通过磁力计可以计算设备的左右、前后倾斜角度,广泛应用于手机各种的应用中。...

大学霸
31分钟前
0
0
mesos:Authentication timed out

最近当slave开始慢慢部署异地集群的时候又碰上了这个问题 I0717 10:27:11.695762 28852 slave.cpp:895] New master detected at master@192.168.2.161:5050I0717 10:27:11.695811 28852 sl......

xueyi28
37分钟前
0
0
赋予用户库的读写权限

1、创建用户 CREATE USER 'test'@'%' IDENTIFIED BY '15ht46389012t'; #'%' - 所有情况都能访问;‘localhost’ - 本机才能访问;’192.168.1.2‘ - 指定 ip 才能访问 2、赋予权限 grant al...

xixingzhe
38分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部