ios-Block深入解析
第一部分:block定义
`
@property (nonatomic, strong) void(^block1)();//定义一个没有返回值没有参数的block
@property (nonatomic, strong) int(^block2)();//定义一个有返回值没有参数的block
@property (nonatomic, strong) int(^block3)(NSString *value);//定义一个有返回值有参数的block
`
第二部分:block声明以及调用
`
//block的声明
self.block1 = ^{
NSLog(@"这是block1");
};
self.block2 = ^{
return 2;
};
self.block3 = ^(NSString *value){
return 3;
};
//调用block
self.block1();
self.block2();
self.block3(@"3");
`
这里注意一点:block的相当于保存了一段代码块,只有当block被调用的时候,才会调用那段保存的代码块。
__block关键字的使用
在Block的{}体内,是不可以对外面的变量进行更改的,比如下面的语句:
`
- (void)viewDidLoad
{
//将Block定义在方法内部
int x = 100;
void (^sumXAndYBlock)(int) = ^(int y){
x = x+y;
printf("new x value is %d",x);
};
sumXAndYBlock(50);
}
`
这段代码有什么问题呢,Xcode会提示x变量错误信息:Variable is not assigning (missing __block type),这时候给int x = 100;语句前面加上__block关键字即可,如下,
`
__block int x = 100;
`
这样在Block的{}体内,就可以修改外部变量了。
第三部分:block的传值
传值分为两种:正向传值和逆向传值。
正向传值就是从一个控制器跳转到另一个控制器,这种处理方法一般是在第二个控制器的.h里面定义一个属性。利用属性进行传值。
逆向传值可以使用代理传值和block传值,
第一种代理传值
//第一个控制器
`
#import "ViewController.h"
#import "modalViewController.h"
@interface ViewController ()<modalViewControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
modalViewController *modalVC = [[modalViewController alloc]init];
modalVC.view.backgroundColor = [UIColor redColor];
modalVC.delegate = self;
[self presentViewController:modalVC animated:YES completion:nil];
}
- (void)modalViewController:(modalViewController *)VC sendValue:(NSString *)value{
NSLog(@"%@",value);
}
`
`
//第二个控制器
#import <UIKit/UIKit.h>
@class modalViewController;
@protocol modalViewControllerDelegate<NSObject>
@optional
- (void)modalViewController:(modalViewController *)VC sendValue:(NSString *)value;
@end
@interface modalViewController : UIViewController
@property (nonatomic, weak) id<modalViewControllerDelegate> delegate;
@end
`
`
//第二个控制器
#import "modalViewController.h"
@interface modalViewController ()
@end
@implementation modalViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if ([_delegate respondsToSelector:@selector(modalViewController:sendValue:)]) {
[_delegate modalViewController:self sendValue:@"123"];
}
}
@end
`
block逆向传值
//第一个控制器
`
#import "ViewController.h"
#import "modalViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
modalViewController *VC = [[modalViewController alloc]init];
VC.block = ^(NSString *value){
NSLog(@"____%@",value);
};
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
modalViewController *VC = [[modalViewController alloc]init];
VC.view.backgroundColor = [UIColor blueColor];
[self presentViewController:VC animated:YES completion:nil];
VC.block = ^(NSString *value){
NSLog(@"%@",value);
};
}
@end
`
第二个控制器
#import <UIKit/UIKit.h> @interface modalViewController : UIViewController @property (nonatomic, strong) void(^block)(NSString *value); @end
`
#import "modalViewController.h"
@interface modalViewController ()
@end
@implementation modalViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if (_block) {
_block(@"123");
}
}
@end
`
现在假设有一个需求,就是在是第一个控制器上有一个lable和一个button,button点击跳转到第二个控制器,在第二个控制器上有一个textField,textField上输入的字符串跳转回第一个控制器上lable上显示,这是写的demo