Block语法

转:http://www.cnblogs.com/Logen/p/3340825.html

Block语法是IOS4.0+引进的,类似于函数指针的语法。

  1. Block最大的特征作用:Block可以在函数中声明、实现。
  2. 它对局部变量只读。block要使用外面的变量的话必须声明__block或static 修饰变量,改为可读写。
  3. Block可以作另一个Block函数的参数(用作回调)。或函数返回值(不常用)。
  4. Block有2种写法。可写成单行。语法如下
      int (^aBlock)(int,int);                     //声明:返回值类型  (^名字)(参数);

      aBlock = ^(int a,int b) { return a + b; }; 

                或

      int (^aBlock)(int,int) = ^(int a,int b) { return a + b; };//内联,可以写在一行

                调用

      aBlock(10,4);

       5.参数传递的过程都是赋值(等号=)的过程。

------------------------------------------------------------------Demo1----------------------------------------------------------

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    
    //block定义,最好命名中又Block
    int (^aBlock)(int,int);
    //相当于函数实现
    __block int num = 10;
    aBlock = ^(int a,int b)
    {
        num++;//对局部变量只读,通过__block或static 修饰变量改为可读写
        return a + b+num;
    };
    
    int c = aBlock(10,4);
    NSLog(@"c = %d",c);
    
    [self.window makeKeyAndVisible];
    return YES;
}

ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。

在何时使用inline函数:
首先,你可以使用inline函数完全取代表达式形式的宏定义。
另外要注意,内联函数一般只会用在函数内容非常简单的时候,这是因为,内联函数的代码会在任何调用它的地方展开,如果函数太复杂,代码膨胀带来的恶果很可能会大于效率的提高带来的益处。内联函数最重要的使用地方是用于类的存取函数。
------------------------------------------------------------------Demo2----------------------------------------------------------
 

Block可以作另一个Block函数的参数-回调例子:

AppleProduct.h

typedef int  (^Block)(int,int);//定义了Block的类型,用Block就可以声明变量

@interface AppleProduct : NSObject

-(void)openApp:(Block )aBlock;//这里的aBlock是一个typedef里形式的Block函数

@end

AppleProduct.m

#import "AppleProduct.h"

@implementation AppleProduct

-(void)openApp:(Block)aBlock       //这里的aBlock是一个typedef里形式的Block函数,参数传递的过程都是赋值(等号=)的过程。函数回调
{ 
  int c = aBlock(20,3);
  NSLog(
@"c = %d",c);
}
@end

AppDelegate.m

AppleProduct *iphone = [[AppleProduc alloc]init];
    int(^aBlock)(int,int) = ^(int x,int y){return x+y;};//block实现
    [iphone openApp:aBlock];

------------------------------------------------------------------Demo3----------------------------------------------------------

BViewController.h

typedef void(^BLOCK) (NSString *str,NSArray *arr);

@interface BViewController : UIViewController

+(void)senderWithData:(BLOCK )aDataOfFun;

@end

BViewController.m

+(void)senderWithData:(BLOCK )aDataOfFun
{
    NSString *str = @"123";
    NSArray *arr = [NSArray arrayWithObjects:@"a",@"b", nil];
    aDataOfFun(str,arr);
}

RootViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    [BViewController senderWithData:^(NSString *str, NSArray *arr) {
        NSLog(@"%@,%@",str,arr);
    }];
    
}

block 应用

  假设我们熟悉代理递值的话,对代理我们可能又爱有恨!我们先建立模型A页面 push B页面,如果把A页面的值传递到B页面,属性和单例传值可以搞定!但是如果Pop过程中把B页面的值传递到A页面,那就可以用单例或者代理了!说到代理,我们要先声明协议,创建代理,很是麻烦。常常我们传递一个数值需要在两个页面间写很多代码,这些代码改变页面的整体顺序,可读性也打了折扣。所以,此时,block是一种优化方案!

------------------------------------------------------------------Demo4----------------------------------------------------------

block传值取缔代理过程(NIB工程)

BViewController.h

typedef void (^Block) (NSString *);

@interface BViewController : UIViewController
@property (retain, nonatomic) IBOutlet UITextField *userTextField;
@property (retain, nonatomic) IBOutlet UIButton *nextBtn;

@property(copy,nonatomic)Block cwBlock;

-(IBAction)btnClick:(id)sender;

@end

BViewController.m

#import "BViewController.h"

@implementation BViewController
@synthesize  cwBlock = _cwBlock;

-(IBAction)btnClick:(id)sender
{
    
    self.cwBlock(self.userTextField.text);
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc {
    Block_release(_cwBlock);
    [_userTextField release];
    [_nextBtn release];
    [super dealloc];
}
@end

AViewController.h

@interface AViewController : UIViewController

@property (retain, nonatomic) IBOutlet UITextField *userTextField;
@property (retain, nonatomic) IBOutlet UIButton *finshBtn;

-(IBAction)finshBtn:(id)sender;

@end

AViewController.m

#import "AViewController.h"
#import "BViewController.h"

@implementation AViewController

-(IBAction)finshBtn:(id)sender
{
    BViewController *bVC = [[BViewController alloc]initWithNibName:@"BViewController" bundle:nil];
    bVC.cwBlock = ^(NSString *text)
    {
        self.userTextField.text = text;
    };
    [self presentViewController:bVC animated:YES completion:^{
        
    }];
    
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc
{
    [_userTextField release];
    [_finshBtn release];
    [super dealloc];
}
@end
  • 枚举——通过block获取枚举对象或控制枚举进程
  • View动画——简单明了的方式规定动画
  • 排序——在block内写排序算法
  • 通知——当某事件发生后执行block内的代码
  • 错误处理——当错误发生时执行block代码
  • 完成处理——当方法执行完毕后执行block代码
  • GCD多线程——多线程控制
原文地址:https://www.cnblogs.com/huen/p/3518720.html