转自:http://blog.sina.com.cn/s/blog_67419c420100vmkt.html
1.为什么要使用blocks
将一个blocks作为函数或者方法的参数传递,可以使函数或者方法在恰当的点实现回调。以各种NSNotification类为例子,传统的方法是一个对象添加自己作为此通知的观察者,实现处理接到通知应该调用的方法(通过addObserver....)。
如下:
- (void)viewDidLoad {
|
[super viewDidLoad]; |
[[NSNotificationCenter defaultCenter] addObserver:self |
selector:@selector(keyboardWillShow:) |
name:UIKeyboardWillShowNotifi |
} |
|
|
- (void)keyboardWillShow:(NSNotification *)notification {
|
// Notification-handling code goes here. |
} |
然而通过方法 我们也可以实现对通知的监控。
addObserverForName:object:queue:usingBlock: 实现如下:
- (void)viewDidLoad {
|
[super viewDidLoad]; |
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotifi |
object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
// Notification-handling code goes here. |
}]; |
} |
2.系统框架API中的blocks
另一个使用blocks的明显动机就是系统框架中提供了很多方法和函数用blocks作为参数。一般都存在于:
completion handlers,notification handlers,error handlers,enumeration,view animation and transitions,sorting 中,下面讲详细介绍。
(1)completion and Error handlers
animateWithDuration:animations:completion: - (IBAction)animateView:(id)sender { CGRect cacheFrame = self.imageView.frame; [UIView animateWithDuration:1.5 animations:^{ CGRect newFrame = self.imageView.frame; newFrame.origin.y = newFrame.origin.y + 150.0; self.imageView.frame = newFrame; self.imageView.alpha = 0.2; } completion:^ (BOOL finished) { if (finished) { // Revert image view to original. sleep(3); self.imageView.frame = cacheFrame; self.imageView.alpha = 1.0; } }]; }
一些框架方法有error handlers,和completion handlers很相似。这些方法当其因为一些错误条件不能完成自己的任务的时候,调用这些error handlers blocks。我们典型的实现这些error handlers去通知用户出现错误。
(2)Notification handlers
- (void)applicationDidFinishLaun |
opQ = [[NSOperationQueue alloc] init]; |
[[NSNotificationCenter defaultCenter] addObserverForName:@"CustomOperationCompleted |
object:nil queue:opQ |
usingBlock:^(NSNotification *notif) {
|
NSNumber *theNum = [notif.userInfo objectForKey:@"NumberOfItemsProcessed"]; |
NSLog(@"Number of items processed: %i", [theNum intValue]); |
}]; |
} |
上面的方法要求传入一个NSOperationQueue实例,因此应用程序可以指定执行block handler 的execution context。
(3)Enumeration
for (id item in collection) {
|
// Code to operate on each item in turn. |
} |
NSString *area = @"Europe"; |
NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames]; |
NSMutableArray *areaArray = [NSMutableArray arrayWithCapacity:1]; |
NSIndexSet *areaIndexes = [timeZoneNames indexesOfObjectsWithOpti |
passingTest:^(id obj, NSUInteger idx, BOOL *stop) {
|
NSString *tmpStr = (NSString *)obj; |
return [tmpStr hasPrefix:area]; |
}]; |
|
|
NSArray *tmpArray = [timeZoneNames objectsAtIndexes:areaIndexes]; |
[tmpArray enumerateObjectsWithOpti |
usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
[areaArray addObject:[obj substringFromIndex:[area length]+1]]; |
}]; |
NSLog(@"Cities in %@ time zone:%@", area, areaArray); |
enumerateSubstringsInRange:options:usingBlock: enumerateLinesUsingBlock: 下面的代码是使用block去匹配substring。
NSString *musician = @"Beatles"; |
NSString *musicDates = [NSString stringWithContentsOfFile |
@"/usr/share/calendar/calendar.music" |
encoding:NSASCIIStringEncoding error:NULL]; |
[musicDates enumerateSubstringsInRan |
options:NSStringEnumerationByLin |
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
|
NSRange found = [substring rangeOfString:musician]; |
if (found.location != NSNotFound) {
|
NSLog(@"%@", substring); |
} |
}]; |
(4)view animation 和 transitions
ios4.0之后UIView类引入了一些用于动画和view transitions的带block参数的方法。block参数分两类:
下面的代码讲述了animateWithDuration:animations:completion:方法的用法。
[UIView animateWithDuration:0.2 animations:^{
|
view.alpha = 0.0; |
} completion:^(BOOL finished){
|
[view removeFromSuperview]; |
}]; |
这个动画就是让view逐渐消失,然后从父视图上移除。
下面的代码段实现了两个views 的flip transitions。
[UIView transitionWithView:containerView duration:0.2 |
options:UIViewAnimationOptionTra |
[fromView removeFromSuperview]; |
[containerView addSubview:toView] |
} |
completion:NULL]; |
(5)sorting
foundation framework声明了NSComparator类型用于比较两个元素。
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
NSComparator是一个block类型,用于两个对象的比较,然后返回一个NSComparisonResult值。下面是一个例子:
NSArray *stringsArray = [NSArray arrayWithObjects: |
@"string 1", |
@"String 21", |
@"string 12", |
@"String 11", |
@"String 02", nil]; |
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | |
NSWidthInsensitiveSearch |
NSLocale *currentLocale = [NSLocale currentLocale]; |
NSComparator finderSort = ^(id string1, id string2) {
|
NSRange string1Range = NSMakeRange(0, [string1 length]); |
return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale]; |
}; |
NSLog(@"finderSort: %@", [stringsArray sortedArrayUsingComparat |
3.block 和concurrency
浙公网安备 33010602011771号