继上篇我们聊的delegate后,这节我们一块聊聊这个block.
块与函数类似,只不过是直接定义在另一个函数里的,和定义它的那个函数共享同一个范围的东西。块用"^”符号表示,后边跟一个大括号,括号里边是块的具体实现代码。
^{
//block implementation
}
块其实就是个值,而且有相关类型,与int,float等对象都是一样的,也可以把块赋给变量,然后像使用其它变量那样来使用它。
块的强大之处在于:在声明它的范围里,所有变量都可以为其所捕获。
默认情况下,块所捕获的变量是不可以在块中修改的,例如:
// <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
// <#statements#>
// };
int additional = 5;
int (^addBlock)(int,int) = ^(int a,int c) {
return a + c + additional;
};
int add = addBlock(3,4);
NSLog(@"%d",add); //-->3+4+5=12
可以直接使用,可是肯定是会有需求的,我们有时候需要在块中修改外部的变量,怎么弄?如下图,会提示我们少了__block.
于是我们这样弄,问题就完美解决了:
__block int additional = 5;
int (^addBlock)(int,int) = ^(int a,int c) {
additional = 6;
return a + c + additional;
};
int add = addBlock(3,4);
NSLog(@"%d",add); //-->3+4+5=13
在开发中block我用到了两种情况,要不就是通过block来传值,要不就是通过block来传事件,下边我讲分两部分来讲block的传值和block的传事件。
block重命名,typedef
//typedef <#returnType#>(^<#name#>)(<#arguments#>);
typedef void(^callbackBlock)(NSString *tempStr,NSString *tempStr2,NSInteger count);
typedef NSString *(^callBlock)(NSString *str1,NSString *str2,NSString *str3);
由上边我们可以看出
返回值类型 block名字 传入的参数(可以是一个,可以是多个,可以没有)
第一:block传值
block传值在我理解来就是比如说是两个界面,界面之间的传值,一个界面的值生成后,通过block保存起来,然后,block里边就有第一个界面的值了,有了第一个值之后,通过block把值传到第二个界面,当然了这样说可能更容易理解点,其实不是这样的,真正的应该是在block代码块中的代码是不会执行的直至调用block的时候,block中的代码块才会被执行,给一个demo,他要实现的就是第二个界面的textField中的内容传给第一个界面的label上,demo如下:
viewCOntroller.h中
#import <UIKit/UIKit.h>
@interface ViewController :UIViewController
@property (nonatomic,strong)UIButton *clickButton;
@property (nonatomic,strong)UILabel *showLabel;
@end
viewController.m中
#import "ViewController.h"
#import "pushViewController.h"
@interfaceViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColorbrownColor];
self.clickButton = [UIButtonbuttonWithType:UIButtonTypeSystem];
self.clickButton.frame =CGRectMake(10,200,50,50);
[self.clickButtonaddTarget:selfaction:@selector(click:)forControlEvents:UIControlEventTouchUpInside];
self.clickButton.backgroundColor = [UIColorredColor];
[self.viewaddSubview:self.clickButton];
self.showLabel = [[UILabelalloc]initWithFrame:CGRectMake(10,100,100,50)];
self.showLabel.backgroundColor = [UIColoryellowColor];
[self.viewaddSubview:self.showLabel];
}
- (void)click:(UIButton *)sender {
NSLog(@"********");
pushViewController *push = [[pushViewControlleralloc]init];
push.block = ^(NSString *str) {
self.showLabel.text = str;
};
[self.navigationControllerpushViewController:pushanimated:YES];
}
@end
#import <UIKit/UIKit.h>
typedefvoid (^ blockPush)(NSString *textFieldStr);
@interface pushViewController :UIViewController
@property (nonatomic,copy)blockPush block;
@property (nonatomic,strong)UITextField *textField;
@end
pushViewController.m中
#import "pushViewController.h"
@interfacepushViewController ()
@end
@implementation pushViewController
- (void)viewDidLoad {
[superviewDidLoad];
self.textField = [[UITextFieldalloc]init];
self.textField.frame =CGRectMake(50,200,200,50);
self.textField.placeholder =@"place input word";
self.view.backgroundColor = [UIColorcolorWithRed:0.6green:0.6blue:0.2alpha:1];
self.textField.clipsToBounds =YES;
self.textField.borderStyle =UITextBorderStyleLine;
[self.viewaddSubview:self.textField];
UIBarButtonItem *backItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:selfaction:@selector(backClick:)];
self.navigationItem.leftBarButtonItem = backItem;
}
- (void)backClick:(UIBarButtonItem *)sender {
if (self.block) {
self.block(self.textField.text);
}
[self.navigationControllerpopViewControllerAnimated:YES];
}
@end
第二:block传事件
还是那个实现,我们这次用block来实现,demo如下:
viewController.m 中
#import "ViewController.h"
#import "blockTest.h"
@interfaceViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
blockTest *blockText = [[blockTestalloc]init];
[blockText startTimer];
blockText.showBlock = ^() {
UIAlertController *alert = [UIAlertControlleralertControllerWithTitle:@"alert"message:nilpreferredStyle:UIAlertControllerStyleAlert];
[alertaddAction:[UIAlertActionactionWithTitle:@"Cancel"style:UIAlertActionStyleDestructivehandler:nil]];
[selfpresentViewController:alertanimated:YEScompletion:nil];
};
}
@end
#import<Foundation/Foundation.h>
typedefvoid (^showAlertBlock)();
@interface blockTest :NSObject
@property (nonatomic,copy)showAlertBlock showBlock;
- (void)startTimer;
@end
blockTest.m中
#import "blockTest.h"
@implementation blockTest
- (void)startTimer {
[NSTimerscheduledTimerWithTimeInterval:5.0ftarget:selfselector:@selector(showAlert)userInfo:nilrepeats:YES];
}
- (void)showAlert {
if (self.showBlock) {
self.showBlock();
}
}
@end