二:基本语法
Block可以看成一个语句块或者是很多时候当做匿名函数来使用。
- (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // delay = 0.0, options = 0, completion = NULL
- [ UIView animateWithDuration:10 animations:^{
- NSLog(@"%@,",@"block");
- }];
简单以这句函数来看。
animations参数接受一个block函数块。我们直接可以^{};来书写这个block。
然后看上面函数申明,我们看到animations接受的参数是这么申明的 (void(^)(void))animations;
这个也好理解,我们知道参数都需要一个申明一个类型比如
(NSTimeInterval)duration。(void(^)(void))其实就是block的一种常见格式的申明。里面还需要分为 :
第一个void是指的是block函数无返回,即{}执行玩没有返回值。(^)是固定规范,表明这是个block类型的。后面的()里表示block接受参数
当然,这边是(void)我们知道,不接受参数。
官方截图如下:
1.如何申明一个block函数
int(^testBlock)(int a,int b);
返回值类型 (^block名字)(传入参数)
2.OC申明一个带有block参数的函数
-(void)textF:(Bool (^)(id a,id b)) bBlock;
这个就如我们上面看到animations,基本和申明很类似,就是名称换到外面去了。
(返回类型 (^)(传入参数))block形参名
然后发现用C代码申明方法时:
void
dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
3.申明后实现一个block函数块
^(int a,int b){
//code;
}
- extern NSInteger CounterGlobal;
- static NSInteger CounterStatic;
- {
- NSInteger localCounter = 42 ;
- __block char localCharacter;
- void (^aBlock)( void ) = ^( void )
- {
- ++ CounterGlobal ; //可以存取。
- ++ CounterStatic ; //可以存取。
- CounterGlobal = localCounter; //localCounter在block 建立时就不可变了。
- localCharacter = 'a' ; //设定外面定义的localCharacter 变数。
- };
- ++localCounter; //不会影响的block 中的值。
- localCharacter = 'b' ;
- aBlock(); //执行block 的内容。
- //执行完后,localCharachter 会变成'a'
三、页面之间的回调block,更新ui:
OneViewController.m
UILabel *label1 = (UILabel *)[self.view viewWithTag:1001];
TwoViewController *two = [[TwoViewController alloc]init];
[self.navigationController pushViewController:two animated:YES];
__block int test = 0;//如果不加_block会报错
two.block = ^(NSString *str){
label1.text = str;
test = 1;
};
two.block(@"222");
NSLog(@"---> %d",test);
[two release];
[label1 release];
TwoViewController.h
#import <UIKit/UIKit.h>
typedef void (^aBlock)(NSString *str);
@interface TwoViewController : UIViewController<UITextFieldDelegate>
@property (nonatomic, copy)aBlock block;
@end
TwoViewController.m
block(textField.text);//回调更新OneViewController中的label1 UI