序言
block:简单来说就是一段代码块,block里面存在可执行代码,可以在函数内进行使用;也可以作为函数中形参进行使用;最常用的应该是替换delegate来进行回调或者传值.
注意:block只是声明和保留了一段代码块,必须要调用才会执行里面的代码.
基本结构
block结构:返回值类型(^Block名字)(参数列表);
//
void(^myBlock)(NSString *) = ^( NSString * n1){
NSLog(@"block");
}
(void)表示的是返回值,^:block的标示符,myBlock:这个block块的名称,(NSString * )表示形参.
调用:myBlock(@"124");
基本用法
//无参数无返回值
void(^myBlock2)(void) = ^{
SPLog(@"come on 2");
};
myBlock2();
//有参数无返回值
void(^myBlock1)(NSString *,NSUInteger) = ^(NSString *n1,NSUInteger i1){
SPLog(@"come on 1 - %@,%ld",n1,i1);
};
myBlock1(@"2b_block",2);
//有参数有返回值
NSString *(^myBlock3)(NSString *) = ^(NSString *n1){
return [n1 stringByAppendingString:@"-143"];
};
NSString * bn1 = myBlock3(@"341");
SPLog(@"%@",bn1);
修改局部变量
block内是不能直接修改block外变量的值的.
如果需要修改,被修改的变量必须用__block
来修饰(注意是2个”_“).
//修改局部变量
__block NSUInteger i2 = 10;
void(^myBlock4)(NSUInteger) = ^(NSUInteger i3){
i2 = i3 + 10;
SPLog(@"block 内i2 = %ld",i2);
};
SPLog(@"block 外i2 = %ld",i2);
myBlock4(i2);
避免循环引用
在类:Block1ViewController中存在2个变量.
//
@property(nonatomic,copy)void(^b1)(void);
@property(nonatomic,strong)NSString * myName;
在类:ViewController中viewDidLoad调用:
//避免循环引用
Block1ViewController * b1VC = [[Block1ViewController alloc]init];
b1VC.myName = @"b1-block";
__weak typeof(b1VC) weakObjB = b1VC;
b1VC.b1 = ^(){
NSString * myName = weakObjB.myName;
SPLog(@"%@",myName);
};
b1VC.b1();
b1VC需要__weak typeof(b1VC) weakObjB = b1VC;
使用__weak进行修饰.
简单说明:
首先,b1是Block1ViewController拥有的一个属性,因此Block1ViewController对b1是强引用的;其次,b1对代码块中的属性也是强引用的;所以会导致他们之间相互强引用,从而导致循环引用.
作为函数参数
在类Block1ViewController.h中声明:
-(void)common_from:(void (^)(id message))success;
在类Block1ViewController.m中实现:
//
-(void)common_from:(void (^)(id message))success{
success(@"come from");
}
在类:ViewController中viewDidLoad调用:
//作为参数使用
Block1ViewController * b2VC = [[Block1ViewController alloc]init];
[b2VC common_from:^(id message) {
SPLog(@" -- %@",message);
}];
这一步其实已经实现了值在2个不同类之间传递,但是传递的值有局限性,只能在当前函数里面进行回调,好处是书写较方便.
typedef结合使用
有时候,我们需要声明多个参数值的时候,需要重复编写,而结合typedef可以简化block使用;好处是可以在类的任何方法里面进行回调,但是书写较麻烦.
//.h文件
#import <UIKit/UIKit.h>
typedef void(^nameColor)(void);
@interface Block1ViewController : UIViewController
@property(nonatomic,copy)nameColor name1;
-(void)typedef_from:(nameColor )m1;
@end
//.m文件
#import "Block1ViewController.h"
@implementation Block1ViewController
-(void)typedef_from:(nameColor )m1{
self.name1 = m1;
}
-(void)touchesBegan:(NSSet<UITouch * > * )touches withEvent:(UIEvent *)event{
self.name1();//可以在任何函数内进行调用.
[self dismissViewControllerAnimated:YES completion:nil];
}
一样可以实现类之间的值的传递和delegate协议的处理.