Objective-C-代码块Block回顾

简介:

OC中的代码块是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性。类似于其他语言脚本语言或者编程语言中的闭包或者是Lambda表达式,可能第一眼看上去很怪异,不过开发的过程中会越来越多的用到Block,还是了解多一点比较好。Block方面的内容也有很多,本文从实际使用的角度大概讲一下Block的基本概念和实践。

首先看一个苹果官网的例子:

1
2
3
4
int  (^Multiply)( int int ) = ^( int  num1,  int  num2) {
     return  num1 * num2;
};
int  result = Multiply(7, 4);  // Result is 28.

 上面的代码定义了一个Block,类似于C#中的委托,int表示返回类型,^是关键标示符,(int,int)是参数类型,不过需要注意的,正常的方式是将返回类型用()包裹,这里是将Block的名称包裹,网上有一个类似的图片,大家可以参考一下:

 

Block除了能够定义参数列表、返回类型外,还能够获取被定义时的词法范围内的状态(将变量作为参数传递之后,可以修改之后返回).Block都是一些简短代码片段的封装,适用作工作单元,通常用来做并发任务、遍历、以及回调。下面看一个通知的例子:

1
2
3
4
5
6
7
8
9
10
- ( void )viewDidLoad {
    [ super  viewDidLoad];
     [[ NSNotificationCenter  defaultCenter] addObserver: self
         selector: @selector (keyboardWillShow:)
         name:UIKeyboardWillShowNotification object: nil ];
}
  
- ( void )keyboardWillShow:( NSNotification  *)notification {
     // Notification-handling code goes here.
}

  以上是调用addServer方法的例子,不过也可以这么写:

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

 苹果官网这个使用Block的例子如果第一次看可能不是那么好理解,如果仔细的看addServerName的定义发现:

1
- ( id  < NSObject >)addObserverForName:( NSString  *)name object:( id )obj queue:( NSOperationQueue  *)queue usingBlock:( void  (^)( NSNotification  *note))block  NS_AVAILABLE (10_6, 4_0);

其中Block参数定义的时候是这样的:

1
( void  (^)( NSNotification  *note))block  NS_AVAILABLE (10_6, 4_0)

 括号包裹起来的内容,第一个是返回值类型,之后的用用括号包裹^,之后的 话才是传递类型,基于以上的理解,可以这么写:

1
2
3
4
5
void (^MyBlock)( NSNotification  *)=^( NSNotification  *note){
      note= nil ;
  };
  [[ NSNotificationCenter  defaultCenter] addObserverForName:UIKeyboardWillShowNotification
                                                    object: nil  queue:[ NSOperationQueue  mainQueue] usingBlock:MyBlock];

 Block在苹果的API文档中随处看见其身影,常见的情况任务完成时回调处理,消息监听回调处理,错误回调处理,枚举回调,视图动画、变换,排序,比如说在NSDictionary中的方法中:

1
- ( void )enumerateKeysAndObjectsWithOptions:( NSEnumerationOptions )opts usingBlock:( void  (^)( id  key,  id  obj,  BOOL  *stop))block  NS_AVAILABLE (10_6, 4_0);

任务完成时候的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- ( 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.
                              self .imageView.frame = cacheFrame;
                              self .imageView.alpha = 1.0;
                          }
     }];
}

 通知机制中的处理:

1
2
3
4
5
6
7
8
9
- ( 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]);
     }];
}

 枚举数组的时候的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);

 也可以写一个Block在截取字符串,做一些自己需要的事情:

1
2
3
4
5
6
7
8
9
10
11
12
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);
            }
       }];

  视图动画和转换中的实践:

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

  两个视图之间的动画:

1
2
3
4
5
6
7
[UIView transitionWithView:containerView duration:0.2
                    options:UIViewAnimationOptionTransitionFlipFromLeft
                 animations:^{
                     [fromView removeFromSuperview];
                     [containerView addSubview:toView]
                 }
                 completion: NULL ];

 数组排序的实践:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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]);

本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4254879.html,如需转载请自行联系原作者

相关文章
|
Java 程序员 C语言
Objective-C之Block、GCD好文章推荐
Objective-C之Block、GCD好文章推荐
128 0
|
iOS开发 Swift
Objective-C编程 - 关于Block的要点
1. 首先,我们快速过一下,什么是Block? Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字。 所以,你可以把它认为是匿名函数。 事实上,它和Swift中的闭包(Closure)是一样的。
974 0
|
C++ 存储 iOS开发
Objective-C语法之代码块(block)的使用
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px"> 代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入
1087 0
|
存储 iOS开发 编译器
objective-c ——代码块
<p>通过代码块(block)功能,你就能像对待对象一般,指定要在方法和函数中传递任意代码部分。</p> <p>代码块的声明:</p> <p>int main (int argc, const char * argv[])<br> {</p> <p>@autoreleasepool {</p> <p>void (^myBlock) (NSString *x);//声明变量</p>
879 0
|
4月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
97 2