【Objective-C】代码块(Block)
2015-08-14 10:46
417 查看
一、Block是什么?
1. 是代码段,苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,block可以在任何时候执行;
2. 代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。
脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:
按照调用函数的方式调用块对象变量就可以了:
int result = myBlock(4); // result是 28
3. 和函数的相似性:
1)可以保存代码;
2)有返回值
3)有形参
4)调用方式一样
4. 标识符:^
二、基本使用
1. 定义block变量
Int (^SumBlock)(int,int);//有参数,返回值类型为int
Void (^MyBlock)();//无参数,返回值类型为空
2. 利用block封装代码
1)Block内部可以访问外部变量;
2)默认情况下,Block内部不能修改外部的局部变量
3)给局部变量加上__block关键字(两个下划线哦),则这个局部变量可以在block内部进行修改。
如:
Typedef int(^MyBlock)(int , int);
以后就可以利用这种类型来定义block变量了。----使用这个好处就是:可以使用无数多个变量进行调用(如下面定义了两个变量),传统的方式只能定义一个变量
MyBlock a, b;
a = ^(int a,int b){return a-b;};
MyBlock b2 = ^(int n1,int n2){return n1*n2;}
三、拓展案例
1. 参数是NSString* 的代码块
@class关键字[598:144356] sortArray:(
"abc 0",
"abc 09",
"abc 1",
"abc 13",
"abc 22"
)
3. 代码块要想递归调用,代码快变量必须要是全局变量或者是静态变量,这样程序启动的时候代码块变量就初始化了,就可以递归调用
1. 是代码段,苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,block可以在任何时候执行;
2. 代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。
脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:
按照调用函数的方式调用块对象变量就可以了:
int result = myBlock(4); // result是 28
3. 和函数的相似性:
1)可以保存代码;
2)有返回值
3)有形参
4)调用方式一样
4. 标识符:^
二、基本使用
1. 定义block变量
Int (^SumBlock)(int,int);//有参数,返回值类型为int
Void (^MyBlock)();//无参数,返回值类型为空
2. 利用block封装代码
// 利用block封装代码 // 1.接受两个参数 int (^MyBlock1)(int, int) = ^(int a, int b) { return a + b; }; // 2.无参数形式 int (^MyBlock2)() = ^() { return 20; }; // 3.无参数的省形式 // 2.无参数形式 int (^MyBlock3)() = ^ { return 20; };3. Block访问外部变量
1)Block内部可以访问外部变量;
2)默认情况下,Block内部不能修改外部的局部变量
3)给局部变量加上__block关键字(两个下划线哦),则这个局部变量可以在block内部进行修改。
如:
void test2() { __block int c = 19; // 声明一个block变量 // 可以使用无数多个变量进行调用 MySum sum = ^(int a, int b) { // 如果外部的变量已经用__block关键字修饰,就可以在block内部修改这一个变量 c = 19; return a + b; }; NSLog(@"%i", sum(10, 10)); }4. 利用typedef定义block类型(和指向函数的指针很像)。关于tepedef的作用后面的的文章有介绍typedf讲解
Typedef int(^MyBlock)(int , int);
以后就可以利用这种类型来定义block变量了。----使用这个好处就是:可以使用无数多个变量进行调用(如下面定义了两个变量),传统的方式只能定义一个变量
MyBlock a, b;
a = ^(int a,int b){return a-b;};
MyBlock b2 = ^(int n1,int n2){return n1*n2;}
三、拓展案例
1. 参数是NSString* 的代码块
void (^print)(NSString *x); print = ^(NSString *str){ NSLog(@"print:%@", str); }; print(@"Hello World");2. 代码在字符串数组排序
// 字符串 NSArray *str = [NSArray arrayWithObjects:@"abc 1", @"abc 22", @"abc 13", @"abc 0", @"abc 09", nil]; NSComparator sort = ^(id str1, id str2) { return [str1 compare:str2]; }; NSArray *sortArray = [str sortedArrayUsingComparator:sort]; NSLog(@"sortArray:%@", sortArray);结果是:
@class关键字[598:144356] sortArray:(
"abc 0",
"abc 09",
"abc 1",
"abc 13",
"abc 22"
)
3. 代码块要想递归调用,代码快变量必须要是全局变量或者是静态变量,这样程序启动的时候代码块变量就初始化了,就可以递归调用
static void (^ const blocks)(int) = ^(int i) { if (i > 0) { NSLog(@"num:%d", i); blocks(i - 1); } }; blocks(3);4.在代码块中使用局部变脸和全局变量
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; }局部变量要想再代码块中能够更改的话需要在block里面添加一个__(两个下划线)
相关文章推荐
- Objective-c 中 nil, Nil, NULL和NSNull的区别
- Objective-C中的方法重载与初始化方法
- 《Objective-C基础教程》第10章 对象初始化
- 黑马程序员———API之Object、String和Scanner
- Objective-C 苹果开发文档--02 Defining Classes
- objective-c学习笔记之属性特性(assign , retain , copy , readonly , readwrite , atomic , nonatomic)
- Objective-C 苹果开发文档 01 Introduction
- Objective-C中一个方法如何传递多个参数的理解
- object-c的内存管理
- TypeError:'stepUp' called on an object that does not implement interface HTMLInputElement.
- 深入JavaScript(12)变量对象(Variable Object)
- NSObject的load和initialize方法
- Objective-C马路成魔【12-分类和协议】
- Objective-C:ARC自动释放对象内存
- Objective-C:MRC(引用计数器)在OC内部的可变对象是适用的,不可变对象是不适用的(例如 NSString、NSArray等)
- Objective-C:MRC(引用计数器)获得对象所有权的方式(init、retain、copy等)
- Objective-C:MRC手动释放对象内存举例(引用计数器)
- Delphi 中的 procedure of object
- 为什么不要直接在Object.prototype上定义方法?(JavaScript)
- Object.observe()带来的数据绑定变革