1 block的定义
第一种直接写:
@property (copy) void(^MyBlock)(void);
第二种:(typedef)
typedef void(^MyBlock)(void);
@property (nonatomic, copy) MyBlock block;
2 block的使用
1) block内部能够一直引用全局变量
2) block内部能够一直引用被static修饰的变量
3) block内部能够一直引用被__block修饰的变量
普通的局部变量,block内部只会引用它最近的值(block定义那一刻),不能跟踪它的改变
void test();
int main(int argc, const char * argv[])
{
test();
return 0;
}
int num = 10;
void test5()
{
void (^block)() = ^{
// block内部能够一直引用全局变量
NSLog(@"----num=%d", num); //-->20
};
num = 20;
block();
}
void test4()
{
static int age = 10;
void (^block)() = ^{
// block内部能够一直引用被static修饰的变量
NSLog(@"----age=%d", age); //-->20
};
age = 20;
block();
}
void test3()
{
__block int age = 10;
void (^block)() = ^{
// block内部能够一直引用被__block修饰的变量
NSLog(@"----age=%d", age); //-->20
};
age = 20;
block();
}
void test2()
{
int age = 10;
age = 20;
void (^block)() = ^{
// 普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变
NSLog(@"----age=%d", age);
};
block();
}
void test()
{
int age = 10;
void (^block)() = ^{
// ----age=10
NSLog(@"----age=%d", age); //-->10
};
age = 20;
block();
}
2 block的传值
1 block的使用
AViewController.h
@interface AViewController : UIViewController {
UILabel *valueLabel;//⽤来接收SecondViewController传回的值
}
@end
实现AViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
valueLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 100, 300, 50)];
[self.view addSubview:valueLabel];
UIBarButtonItem *nextBtn = [[UIBarButtonItem alloc] initWithTitle:@"next"
style:UIBarButtonItemStylePlain target:self action:@selector(nextClick)];
self.navigationItem.rightBarButtonItem = nextBtn;
}
- (void)nextClick
{
BViewController *svc = [[BViewController alloc] init];
svc.backValue = ^(NSString *strValue) {//设置SecondViewController⾥边的block属性,
这是本程序的关键
valueLabel.text = strValue;
};
[self.navigationController pushViewController:svc animated:YES];
}
BViewController.h
@interface BViewController : UIViewController
@property (nonatomic, copy) void (^backValue)(NSString *strValue);
@property (nonatomic, retain) UITextField *text;
@end
实现BViewController.m
@implementation BViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
text = [[UITextField alloc] initWithFrame:CGRectMake(10, 50, 300, 40)];
text.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:text];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 110, 60, 30);
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)btnClick
{
self.backValue(self.text.text);//调⽤block⽅法
[self.navigationController popViewControllerAnimated:YES];
}
@end
2 block的注意事项
1,block内的是强引用。当与控制器循环引用,需用弱指针
cell下载图片 http://my.oschina.net/u/2346786/blog/483872
block传值的思路
1,B要传值,即建立block属性 void (^backValue)(NSString *strValue);
然后实现它:self.backValue(要传的值)
2,A要得到B的传值 即实现B的的属性。
AViewController *aVC = [[AViewController alloc] init];
//通过block传值,城市切换
aVC.backValue = ^(NSString *strValue) {
//设置SecondViewController⾥边的block属性,这是本程序的关键
self.cityName = strValue;
};
3,分析blcok属性的写法
返回值-名称-参数
返回值-名称-等号
@property (nonatomic, copy) void (^backValue) (NSString *strValue);
@property (nonatomic, copy) NSString *name; =
4,要配合界面跳转使用
4 block内存优化
可以在控制器使用delloc方法判断有无内存泄露,注意block内对象的强引用,要改为弱引用