小议Block

一.作用

功能与函数相当,可以在使用时定义,让代码作用明了.可以在块中修改全局变量,静态变量,__block修饰的局部变量.

例一:声明实现

int (^Multiply)(int, int) = ^(int num1, int num2) {
    return num1 * num2;
};

int result = Multiply(7, 4); // result is 28

  

例二:调用对比

- (void)viewDidLoad {
   [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(keyboardWillShow:)
        name:UIKeyboardWillShowNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    // Notification-handling code goes here.
}

With the addObserverForName:object:queue:usingBlock: method you can consolidate the notification-handling code with the method invocation:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification
         object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
             // Notification-handling code goes here. 
    }];
}

  

二.系统API中的使用

1.Completion handlers

2.Error handlers

相当于回调函数,完成时开始时出错时调用什么方法那样.

Listing 1-1  A completion-handler block

- (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;
                         }
                     }];
}

  

3.Notification handlers

另一种注册事件的方法.

As with notification-handler methods, an NSNotification object is passed in. The method also takes an NSOperationQueue instance, so your application can specify an execution context on which to run the block handler.

Listing 1-2  Adding an object as an observer and handling a notification using a block

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    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]);
    }];
}

  

4.Enumeration

对于支持遍历器的NSArray, NSDictionary, NSSet,  NSIndexSet,有两种形式的blocks.一种是不返回值的处理型,一种是返回整形的过滤型.两种的参数中有个bool型,当被设置成YES时,跳出遍历.

Listing 1-3  Processing enumerated arrays using two blocks

NSString *area = @"Europe";
NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];
NSMutableArray *areaArray = [NSMutableArray arrayWithCapacity:1];
NSIndexSet *areaIndexes = [timeZoneNames indexesOfObjectsWithOptions:NSEnumerationConcurrent
                                passingTest:^(id obj, NSUInteger idx, BOOL *stop) {
    NSString  *tmpStr = (NSString *)obj;
    return [tmpStr hasPrefix:area];
}];


NSArray *tmpArray = [timeZoneNames objectsAtIndexes:areaIndexes];
[tmpArray enumerateObjectsWithOptions:NSEnumerationConcurrent|NSEnumerationReverse
                           usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                               [areaArray addObject:[obj substringFromIndex:[area length]+1]];
}];

NSLog(@"Cities in %@ time zone:%@", area, areaArray);

NSString类有两种blocks的方法:enumerateSubstringsInRange:options:usingBlock: and enumerateLinesUsingBlock:. 第一种根据你设置的options分割访问特定区域的字符串,第二种仅仅根据行来分割.

Listing 1-4  Using a block to find matching substrings in a string

NSString *musician = @"Beatles";
NSString *musicDates = [NSString stringWithContentsOfFile:
    @"/usr/share/calendar/calendar.music"
    encoding:NSASCIIStringEncoding error:NULL];
[musicDates enumerateSubstringsInRange:NSMakeRange(0, [musicDates length]-1)
    options:NSStringEnumerationByLines
    usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
           NSRange found = [substring rangeOfString:musician];
           if (found.location != NSNotFound) {
                NSLog(@"%@", substring);
           }
      }];

//-------the same
[musicDates enumerateLinesUsingBlock:^(NSString *line,BOOL *stop)
     {
         NSRange found = [line rangeOfString:musician];
         if (found.location != NSNotFound) {
             NSLog(@"%@", line);
         }
     }];

  

5.View animation and transitions

两种:改变视图属性和动画结束回调(不是都必须).

Listing 1-5  Simple animation of a view using blocks

[UIView animateWithDuration:0.2 animations:^{
        view.alpha = 0.0;
    } completion:^(BOOL finished){
        [view removeFromSuperview];
    }];

  

两种场景切换(transitionWithView:duration:options:animations:completion: ),下例实现类似flip-left动画.

Listing 1-6  Implementing a flip transition between two views

[UIView transitionWithView:containerView duration:0.2
                   options:UIViewAnimationOptionTransitionFlipFromLeft                  animations:^{
                    [fromView removeFromSuperview];
                    [containerView addSubview:toView]
                }
                completion:NULL];

  

6.Sorting

比较两个对象大小,用于 NSSortDescriptor, NSArray, and NSDictionary中.

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

Listing 1-7  Sorting an array using an NSComparator block

NSArray *stringsArray = [NSArray arrayWithObjects:
                                 @"string 1",
                                 @"String 21",
                                 @"string 12",
                                 @"String 11",
                                 @"String 02", nil];
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch |
        NSWidthInsensitiveSearch | NSForcedOrderingSearch;
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 sortedArrayUsingComparator:finderSort]);

  

三.Blocks与并发

在Grand Central Dispatch (GCD) and the NSOperationQueue类中使用

参考:https://developer.apple.com/library/ios/#featuredarticles/Short_Practical_Guide_Blocks/_index.html

原文地址:https://www.cnblogs.com/v2m_/p/2171282.html