ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。
下面是理论部分:
1、block的定义
// 声明和实现写在一起,就像变量的声明实现 int a = 10; 2 int (^aBlock)(int, int) = ^(int num1, int num2) { 3 4 return num1 * num2; 5 6 }; 7 // 声明和实现分开,就像变量先声明后实现 int a;a = 10; 8 int (^cBlock)(int,int); 9 cBlock = ^(int num1,int num2) 10 { 11 return num1 * num2; 12 };
其中,定义了一个名字为aBlock的blocks对象,并携带了相关信息:
1、aBlock 有两个形式参数,分别为int类型;
2、aBlock 的返回值为int 类型;
3、等式右边就是blocks的具体实现;
4、^ 带边blocks声明和实现的标示(关键字);
当然,你可以定义其他形式的block。e.g:无返回值,无形式参数等;
void (^bBlock)() = ^() 2 { 3 int a = 10; 4 printf("num = %d",a); 5 };
2、blocks 访问权限
blocks可以访问局部变量,但是不能修改。
int a = 10; 2 int (^dBlock)(int) = ^(int num) 3 { 4 a++;//not work! 5 return num * a; 6 };
此处不能修改的原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a'和a是没有关系的。
这个地方就是函数中的值传递。如果要修改就要加关键字:__block或者static
__block int a = 7; 2 int (^dBlock)(int) = ^(int num) 3 { 4 a++;// work! 5 return num * a; 6 };
3、block的调用
block调用就像调用函数一样。e.g:
int c = aBlock(10,10); <br> bBlock();
下边是在两个viewcontroller之间通过block传值
MainView.h #import <UIKit/UIKit.h> @interface MainView : UIViewController { IBOutlet UIButton* btn; IBOutlet UILabel* labShow; } -(IBAction)push:(id)sender; @end MainView.m #import "MainView.h" #import "SecondView.h" @implementation MainView - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { } return self; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; } -(IBAction)push:(id)sender { SecondView *s = [[SecondView alloc] initwithBlock:Block_copy(^(NSString *str){ NSLog(@"%@",str); labShow.text = str; })]; [self.navigationController pushViewController:s animated:YES]; [s release]; } - (void)viewDidUnload { [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end
Second.h
#import <UIKit/UIKit.h> typedef void (^MyBlock)(NSString *); @interface SecondView : UIViewController { IBOutlet UITextField* txtView; MyBlock my; } -(IBAction)back:(id)sender; -(id)initwithBlock:(MyBlock)str; @end Second.m #import "SecondView.h" @implementation SecondView -(id)initwithBlock:(MyBlock)str { self = [super init]; if(self) { my = str; } return self; } -(IBAction)back:(id)sender { NSString* s = txtView.text; if(my) { my(s); } [self.navigationController popViewControllerAnimated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -(void)dealloc{ Block_release(my); [super dealloc]; } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewDidUnload { [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end