如何在iOS中使用Block
来源:互联网 发布:淘宝靠谱的口红代购 编辑:程序博客网 时间:2024/05/20 20:57
Block可以帮助我们组织独立的代码段,并提高复用性和可读性。iOS4在UIKit中引入了该特征。超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识。
Block是什么样的?
你可以使用^操作符来声明一个Block变量,它表示一个Block的开始。
- int num1 = 7;
- int(^aBlock)(int) = ^)int num2) {
- return num1+nunm2;
- };
在如上代码中我们将Block声明为一个变量,所以可以将它当做一个函数中使用:
- NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56.
我们刚看过了将block当做变量的情况,但通常情况下我们会以内联的方式使用Block,比如在一个变量中。API要么会使用Block在一个对象集合上执行某种操作,要么将其作为一个操作完成后的回调。
- NSComperator compareStringsBlock = ^(id stringA, id stringB) {
- NSRange rangeS = NSMakeRange (0, [stringA length]);
- return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale];
- };
- NSArray *compareSortArray = [arrayOfStringDays sortArrayUsingComparator: compareStringsBlock]);
Block具有将临时函数体创建为表达式的优势。Apple文档中指出:
Block是符合如下要求的匿名内联的代码集:
- 和函数一样具有一个指定类型的参数列表
- 有一个可以推导或声明的返回值类型
- 可以从它被定义的词义范围中捕捉状态
- 可以在需要的时候改变词义范围的状态
- 可以和相同的词义范围中定义的其他的Block共享更改的可能。
- 可以在词义范围(堆栈帧)被销毁后继续共享和修改该词义范围(堆栈帧)的状态。
Block是一个自包含的小代码段,封装了用于遍历(线性遍历)或者回调,可以并发执行的任务单元。
声明和使用Block
Apple文档中介绍了如何将一个Block声明为变量,并将其作为一个函数使用:
- int (^oneFrom)(int) = ^(int anInt) {
- return anInt - 1;
- };
- // 我们创建了一个内联块^(int anInt)... ,其函数体和结果被传到了另外一个名为OneFrom的Block。
- printf("1 from 10 is %d", oneFrom(10));
- // 打印出: "1 from 10 is 9"
- // 这个block函数(distanceTraveled)传入3个float型参数,返回float值。
- float (^distanceTraveled) (float, float, float) =
- ^(float startingSpeed, float acceleration, float time) {
- float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);
- return distance;
- };
你也可以传入一个Block作为一个参数,而不要以如上的方式声明它们,这样就可以在需要将block作为参数的时候以内联代码的方式简单地实现。
- NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil];
- sortFunction(anArray, ^(string *a string *b){
- if ( a == @"cat") return TRUE; });
这样我们就看到一个内联的block代码段占据了最后一个参数(必须是参数列表的最后一个参数)的位置。Cocoa提供了很多使用Block的方法,这样你就可以传入Block作为方法的参数:
- NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];
- NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];
- BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL
- //body of block gets the block literal ^(id obj, NSUInteger idx, Bool *stop)... and the body logic
- test = ^ (id obj, NSUInteger idx, BOOL *stop) {
- if (idx < 5) {
- if ([filterSet containsObject: obj]) {
- return YES;
- }
- }
- return NO;
- };
Apple提供的另外一个例子是:
- __block BOOL found = NO;
- NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];
- NSString *string = @"gamma";
- //we provide below a way of how to enumerate, using our own compare logic
- [aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
- if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {
- *stop = YES;
- found = YES;
- }
- }];
As you can see, it takes a little while to have it sink in but once you get it, it's quite simple. I suggest looking at Apple's documentation, as well as looking at the referenced APIs to see how they are used. Practice makes perfect.
原文出处:http://answers.oreilly.com/topic/2281-how-to-use-blocks-with-ios/
objective-c block 详解
Block
Apple 在C, Objective-C, C++加上Block這個延申用法。目前只有Mac 10.6 和iOS 4有支援。Block是由一堆可執行的程式組成,也可以稱做沒有名字的Function (Anonymous function)。如果是Mac 10.6 或 iOS 4.0 之前的平台可以利用 http://code.google.com/p/plblocks/ 這個project得以支援Block語法。
Apple有一個叫做GCD(Grand Central Dispach)的新功能,用在同步處理(concurrency)的環境下有更好的效率。Block語法產生的動機就是來自於GCD,用Block包好 一個工作量交給GCD,GCD有一個宏觀的視野可以來分配CPU,GPU,Memory的來下最好的決定。
Block其實行為和Function很像,最大的差別是在可以存取同一個Scope的變數值。
Block 實體會長成這樣
^(傳入參數列) {行為主體};
Block實體開頭是"^",接著是由小括號所包起來的參數列(比如 int a, int b, float c),行為的主體由大括號包起來,專有名詞叫做block literal。行為主體可以用return回傳值,型別會被compiler自動辦識出來。如果沒有參數列要這樣寫(void)。
看個列子
^(int a) {return a*a;};
這是代表Block會回傳輸入值的平方值(int a 就是參數列,return a*a; 就是行為主體)。記得主體裡最後要加";"因為是敘述,而整個{}最後也要要加";"因為Block是個物件實體。
用法就是
int result = ^(int a) {return a*a;} (5);
很怪吧。後面小括號裡的5 會被當成a的輸入值然後經由Block輸出5*5 = 25指定給result這個變數。
有沒有簡單一點的方法不然每次都要寫這麼長?有。接下來要介紹一個叫Block Pointer的東西來簡化我們的寫法。
Block Pointer是這樣宣告的
- 如何在iOS中使用Block
- 如何在iOS中使用Block
- 如何在iOS中使用Block
- 如何在IOS中使用block
- 如何在 iOS 5 中使用 Block
- 如何在iOS中使用Block
- 如何在iOS中使用Block
- 如何在iOS中使用Block
- 如何在iOS中使用Block
- 如何在iOS中使用 block
- 如何在iOS中使用Block
- 如何在 iOS 5 中使用 Block (1)
- 如何在 iOS 5 中使用 Block (2)
- 如何在 iOS 5 中使用 Block (1)
- 如何在 iOS 5 中使用 Block (2)
- 如何在 iOS 5 中使用 Block (2)
- 如何在 iOS 5 中使用 Block (2)
- 如何在 iOS 5 中使用 Block (1)
- Java的内存回收机制
- hdu1124(djstra+dfs)
- VS2010如何创建DLL和如何使用外部DLL
- 事务的理解
- 【自动装箱、自动拆箱】享元设计模式:对于小的整数,装箱装成的对象都是同一个
- 如何在iOS中使用Block
- 普京要求下周内批准在克里米亚建俄地方机关计划
- C++ 私有、共有、保护成员的继承方式
- AC自动机算法
- Qt事件基本了解[2014/03/23]
- Java设计模式透析之 —— 模板方法(Template Method)
- 献给汇编初学者-函数调用堆栈变化分析
- 游标,存储过程,触发器
- 中国或将施行两类高考模式 区分技术技能型和学术性更有利于就业