Block 的使用有两种:
.独立Block
.内联Block
 
《一》独立Block 使用方式
 
一、定义一个Block Object,并调用。
 
1.定义
 
// 定义一个Block Object,返回值:NSString;别名:intToString;参数:NSUInteger。

NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){

    NSString *result = [NSString stringWithFormat:@"%lu",(unsignedlong)paramInteger];

    return result;

};
 
2.调用
 
// 调用我们定义的Block Ojbect

NSString *string = intToString();

NSLog(@"string = %@", string);
二、将Block Object 当作参数,在方法之间传递,调用。
 
有时候,我们希望将定义的Block Object作为函数的参数使用,就像其他的数据类型一样。
 
1.为Block Object 定义签名
 
typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger);
 
这就告诉,编译器,我们定义了一个签名(别名)为IntToStringConverter 的Block Object。这个Block返回值为:NSString;参数为:NSUInteger。
 
2.定义使用Block为参数的函数
 
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(IntToStringConverter)paramBlockObject{

    return paramBlockObject(paramInteger);

}
 
这一步,很简单,我们将前面定义的Block作为了一种类型。这种类型为:IntToStringConverter
 
3.调用使用Block为参数的方法
 
 NSString *result = [self convertIntToString: usingBlockObject:intToString];

    NSLog(@"result = %@", result);
调用时,123,和intToString可理解为实参。
 
《二》内联Block 使用方式
 
在此之前,让我们梳理一下需要的代码:
 
1.定义
typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger);
 
2.用Block作为参数的函数
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(IntToStringConverter)paramBlockObject{

    return paramBlockObject(paramInteger);

}
 
3.内联调用
- (void) doTheConversion{

    IntToStringConverter inlineConverter = ^(NSUInteger paramInteger){

        NSString *result = [NSString stringWithFormat:@"%lu", (unsignedlong)paramInteger];

        return result;

    };

    NSString *result = [self convertIntToString:123usingBlockObject:inlineConverter];

    NSLog(@"result = %@", result);

}
 
调用的时候,只需要这样:
[self doTheConversion];

什么是内联Block?

我的理解是,写在方法内部的,编译器在编译阶段无法知道要调用的具体Block内容。

就像上边的例子:

独立Block:在编译阶段,已经就定义好了Block方法:

// 定义一个Block Object,返回值:NSString;别名:intToString;参数:NSUInteger。

NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){

    NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger];

    return result;

};

内联Block:在编译阶段,编译器并不知道所关联的Block是什么。

因为它是在调用doTheConversion方法时,临时分配的(inlineConverter)。红色块。

- (void) doTheConversion{

    IntToStringConverter inlineConverter = ^(NSUInteger paramInteger){

        NSString *result = [NSString stringWithFormat:@"%lu", (unsignedlong)paramInteger];

        return result;

    };

    NSString *result = [self convertIntToString: usingBlockObject:inlineConverter];

    NSLog(@"result = %@", result);

}

同理,就相当于:

- (void) doTheConversion{

     NSString *result =[self convertIntToString:

                               usingBlockObject:^(NSUInteger paramInteger) {

                                   NSString *result = [NSStringstringWithFormat:@"%lu",(unsigned long)paramInteger];

                                   return result;

                               }];

    NSLog(@"result = %@", result);

}

是啊,很多iOS中的方法,用的都是这种方式!对用的就是内联Block!!!

原来如此啊!

先mark到这里吧!

下一步,我们来了解一下,关于Block变量的一些东西!

Block 的变量

1.独立Block 变量的操作。

定义Block:

void (^independentBlockObject)(void) = ^(void){

    NSInteger localInteger = ;

    NSLog(@"local integer = %ld", (long)localInteger);

    localInteger = ;

    NSLog(@"local integer = %ld", (long)localInteger);

};

调用:

independentBlockObject();

输出:

-- ::50.144 DemoVideo[:] local integer = 

-- ::50.147 DemoVideo[:] local integer = 

2.内联Block 变量的操作。

我们知道Object-C中已经有很多用Block作为参数的函数。该Block参数,作为内联Block调用。

于是,就用一个数组比较的方法:

定义:

- (void) simpleMethod{

    NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@"",@"",@"", nil];

    NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {

        if ([obj1 integerValue] > [obj2 integerValue]) {

            return (NSComparisonResult)NSOrderedDescending;

        }

        if ([obj1 integerValue] < [obj2 integerValue]) {

            return (NSComparisonResult)NSOrderedAscending;

        }

        return (NSComparisonResult)NSOrderedSame;

    }];

}

调用:

[self simpleMethod];

输出:

Printing description of sortedArray:

<__NSArrayI 0x1f56d430>(

,

,

)

Printing description of array:

<__NSArrayM 0x1f585ed0>(

,

,

)

我们不用关心,sortedArrayUsingComparator方法的内部实现是什么,但是,它在运行中,调用了内部变量:obj1和obj2

可见:独立Block可以在内部定义变量,访问变量,修改变量!

Block可以读写自己内部的变量,那么对于外部变量,有如何呢 ?

不着急,我们先来归纳一下用于测试的相关代码:

定义Block签名

typedef NSString* (^UserMyBlockFun)(NSUInteger paramInteger);

定义Block为参数的函数

- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(UserMyBlockFun)paramBlockObject{

    return paramBlockObject(paramInteger);

}

定义调用函数:

- (void) doTheConversion{

    __block int outsideVariable=;

    NSString *result =[self convertIntToString:

                              usingBlockObject:^(NSUInteger paramInteger) {

                                  // 访问self

                                  NSLog(@"self = %@", self);

                                  // 访问self的实体变量

                                  NSLog(@"self = %@", self.strName);

                                  int insideVariable=;

                                  insideVariable+=;

                                  // 输出内部变量,没问题,对内部变量可读写

                                  NSLog(@"insideVariable:%d",insideVariable);

                                  // 输出外部变量,可以读取外部变量,但是不能修改,否则将报出一个错误。

                                  // Variable is not assignable(missing __block type specifier)

                                  NSLog(@"outSideVariable:%d",outsideVariable);

//                                  outsideVariable+=3;

                                  NSLog(@"outSideVariable:%d",outsideVariable);

                                  NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger];

                                  return result;

                              }];

    NSLog(@"result = %@", result);

}
 

可见,对于外部普通变量,Block只有读取的权限。

但是,从一个错误:Variable is not assignable(missing __block type specifier)中,也许我们可以知道,

如果,要对外部变量具有写权限,那么就要在变量前,加上“__block”

 __block int outsideVariable=;

这样,就可以读写outsideVariable变量了。

内联Block可以直接访问self;但是,独立Block不能直接访问self,替代方式为,将self作为参数,传递给Block。

如:

// 独立Block

void (^correctBlockObject)(id) = ^(id self){

    // 将self作为参数传递

    NSLog(@"self = %@", self);

    // 访问self变量

    NSLog(@"self = %@", [self strName]);

};

- (void) callCorrectBlockObject{

    correctBlockObject(self);

}

有一点非常重要:

内联Block,调用的外部变量,使用的是复制方式。

运行一下,查看输出就知道了:

- (void) scopeTest{

    NSUInteger integerValue = ;

    // 定义内联Block

    BlockWithNoParams myBlock = ^{

        NSLog(@"Integer value inside the block = %lu", (unsignedlong)integerValue);

    };

    integerValue = ;

    // 调用Block

    myBlock();

    NSLog(@"Integer value outside the block = %lu",(unsigned long)integerValue);

}

如果要使用引用方式,那么就要在变量前加上“ __block”

调用 Block 

关于内联Block,因为其就是写在方法内的,所以,调用起来相对方便。就像iOS中的API,有很多方法,使用了内联Block方式。

关于独立Block,主要使用C语言的函数调用方式。

用例子来说明吧。

1.调用Block

// 定义Block

void (^simpleBlock)(NSString *) = ^(NSString *theParam){

    NSLog(@"the string=%@",theParam);

};

// 调用Block

- (void) callSimpleBlock{

    simpleBlock(@"O'Reilly");

}

2.嵌套调用

// 定义内层Block

NSString *(^trimString)(NSString *) = ^(NSString *inputString){

    NSString *result = [inputString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];

    return result;

};

// 定义外层Block

NSString *(^trimWithOtherBlock)(NSString *) = ^(NSString *inputString){

    return trimString(inputString);

};

// 调用方法

- (void) callTrimBlock{

    NSString *trimmedString = trimWithOtherBlock(@" O'Reilly ");

    NSLog(@"Trimmed string = %@", trimmedString);

}

iOS - Block的简单使用的更多相关文章

  1. iOS Block的简单使用以及__block 和static修饰变量

    简单的代码总结,不足之处多多指教. //简单的使用 -(void)blockOne{ ; int(^BlockOne)(int) = ^(int num2) { return number*num2; ...

  2. 关于Block的简单使用

    Block在整个iOS开发中无所不见,很重要,很重要,文本在这里block的简单使用介绍.我们可以简单地定义.使用block. 1. Block和C的指针函数很像,但比C的函数灵活多了.废话了.... ...

  3. iOS block从零开始

    iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void ...

  4. iOS block并发

    多核运算 在iOS中concurrency编程的框架就是GCD(Grand Central Dispatch), GCD的使用非常简单.它把任务分派到不同的queue队列来处理.开发者把任务代码装到一 ...

  5. iOS Block的本质(一)

    iOS Block的本质(一) 1.对block有一个基本的认识 block本质上也是一个oc对象,他内部也有一个isa指针.block是封装了函数调用以及函数调用环境的OC对象. 2.探寻block ...

  6. iOS Block理解

    以前看到Block觉得也没什么,不就是类似函数的东西,这东西在C#里就是委托,在Java里就是块,有什么稀奇的.但看到一点进阶的内容后,发现这个东西确实有用. 所以做下总结. 一.块的基本用法 块的语 ...

  7. iOS Block界面反向传值

    在上篇博客 <iOS Block简介> 中,侧重解析了 iOS Block的概念等,本文将侧重于它们在开发中的应用. Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C ...

  8. OC block的简单使用

    http://blog.csdn.net/itpeng523/article/details/23965147 一.先用Xcode创建一个空工程 学习block之前先用弄懂c语言的函数指针 看代码: ...

  9. iOS - Block 代码块

    1.Block Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的, ...

随机推荐

  1. 将Unity导出的Eclipse工程转换为AndroidStudio工程

    步骤:1)将unity项目导出到文件夹: 转换到安卓平台,这里只勾选google android project.然后导出到自己新建的文件夹. 2)打开导出的文件夹,看到如下内容.这是unity5.x ...

  2. windows下caffe安装配置、matlab接口

    一.CommonSettings.props caffe下载后解压.源代码文件夹caffe-master,到该文件夹下的windows文件夹下,将CommonSettings.props.exampl ...

  3. QT 随机数生成

    下面总结了QT中随机生成的方法(仅供学习参考),分为旧方法和新方法,一般来说,旧的方法已经被抛弃,在开发新的应用中推荐使用新方法.  C++ Code  12345678910111213141516 ...

  4. linux中通过awk进行文本的对齐格式化处理?awk printf左对齐?

    需求描述: 今天在对一个从excel文件中粘出来的内容进行整理的时候,发现格式很乱,就想用awk工具格式化一下,在此记录一下. 操作过程: 1.从excel中复制出来的内容 job_name    j ...

  5. Laravel5.1 填充数据库

    当我们创建好表结构后 通常都要生成一些测试用的数据来测试,应对这个场景呢 Laravel提供了相当好的服务 --seed Laravel的seeder都会放在:/database/seeders 目录 ...

  6. association 的使用

    <resultMap id="wmsTaskMap" type="WmsTask"> <id column="ID" jd ...

  7. UVA 1232 - SKYLINE(线段树)

    UVA 1232 - SKYLINE option=com_onlinejudge&Itemid=8&page=show_problem&category=502&pr ...

  8. 8 -- 深入使用Spring -- 2... Spring的“零配置”支持

    8.2 Spring的“零配置”支持 Spring支持使用Annotation来代替XML配置文件.

  9. PHP代码审计笔记--命令执行漏洞

    命令执行漏洞,用户通过浏览器在远程服务器上执行任意系统命令,严格意义上,与代码执行漏洞还是有一定的区别. 0x01漏洞实例 例1: <?php $target=$_REQUEST['ip']; ...

  10. MongoDB(四)-- 主从配置

    一.前言 虽然MongoDB官方已经不建议使用主从模式了,但是 熟悉下 也是有用的,替代方案是采用副本集的模式.slave默认情况下是不支持读写的,但是master会把数据同步到slave,不支持客户 ...