block
Blocks areoften used to simplify common tasks such as collection enumeration, sorting andtesting. They also make it easy to schedule tasks for concurrent orasynchronous execution using technologies like Grand Central Dispatch (GCD).
声明block:
void(^simpleBlock)(void);
定义block:
simpleBlock= ^{
NSLog(@"This is a block");
};
声明和定义在一起:
void(^simpleBlock)(void) = ^{
NSLog(@"Thisis a block");
};
调用block:
simpleBlock();
带返回值和参数的block:
double(^multiplyTwoValues)(double, double) =
^(doublefirstValue, double secondValue) {
returnfirstValue * secondValue;
};
double result = multiplyTwoValues(2,4);
NSLog(@"The result is %f",result);
If you needto be able to change the value of a captured variable from within a block, youcan use the__block storage type modifier on theoriginal variable declaration.
如果block是递归调用的,必须设置成 __block。e.g.
__blockint (^recursiveBlock)(int) = ^(int param) {
if (param ==1) {
return 1;
}
return (param--) * recursiveBlock(param);
};
recursiveBlock(5); // 计算5的阶乘
You Can Pass Blocks as Arguments toMethods or Functions
-(void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock;
The (void (^)(void)) specifies that theparameter is a block that doesn’t take any arguments or return any values. Theimplementation of the method can invoke the block in the usual way:
- (void)beginTaskWithCallbackBlock:(void(^)(void))callbackBlock {
...
callbackBlock();
}
ABlock Should Always Be the Last Argument to a Method
Objects Use Properties to Keep Track ofBlocks
The syntax to define a property to keeptrack of a block is similar to a block variable:
@interfaceXYZObject : NSObject
@property (copy) void (^blockProperty)(void);
@end
Note:You should specify copy as the property attribute, because a block needs to becopied to keep track of its captured state outside of the original scope.
A block property is set or invoked likeany other block variable:
self.blockProperty = ^{
...
};
self.blockProperty();
typedef void(^BlockCC)(void);
// e.g.更新myTableview并显示最后一行
if (dataArray.count >0) {
[myTableViewreloadData];
// reloadData后不能直接调用scrollToRowAtIndexPath,有可能lastIndex在table中不存在,
// 所以要[NSObjectperformBlock:afterDelay:0];
[myTableViewretain]; //防止关闭视图,myTableView释放之后scrollToBottom出错
NSIndexPath*lastIndex = [NSIndexPathindexPathForRow:dataArray.count-1inSection:0];
void(^scrollToBottom)(void) = ^{
[myTableViewscrollToRowAtIndexPath:lastIndexatScrollPosition:UITableViewScrollPositionBottomanimated:YES];
[myTableViewrelease];
};
[NSObjectperformBlock:scrollToBottomafterDelay:0];
}