一. block的声明、调用、实现
1. block的声明
返回值(^block变量名)(参数);
例如:
// 声明block
void(^blockName)(int a);
// 这行代码,blockName是block的名字,其余是block的类型
2. block的调用
block变量名(参数);
例如:
blockName(10);
注意:只有调用block才会实现调用block里面的代码。
3. block的实现
block声明 = ^(参数){};
例如:
blockName = ^(int a){
NSLog(@"%d,a);
};
也可以把这一步和上一步合起来写,就是声明并且实现,如下:
void(^blockName)(int a) = ^(int a){
NSLog(@"%d,a);
};
4. 注意点
- 如果没有参数,参数可以省略。
void(^block1)() = ^{
NSLog(@"调用了block1");
};
- 如果有参数,定义的时候,必须要写参数,而且必须要有参数变量名。
void(^block2)(int) = ^(int a){
NSLog(@"%d,a);
};
- block返回值可以省略,不管有没有返回值,都可以省略。
int(^block3)() = ^int{
return 3;
};
所以可以省略如下:
int(^block3)() = ^{
return 3;
};
5. typedef
可以使用typedef定义block的类型,方便后面直接使用
//定义MyBlock
typedef double(^MyBlock)(double, double);
MyBlock area = ^(double x, double y) {
return x * y;
};
MyBlock sum = ^(double a, double b) {
return a + b;
};
NSLog(@"%.2f", area(10.0, 20.0));
NSLog(@"%.2f", sum(10.0, 20.0));
二. block在实际开发中的使用
1. 把block定义为属性,保存代码块
@interface ViewController ()
// block怎么声明,就怎么定义成属性
@property (nonatomic,strong) void(^block)();
@end
@implementation ViewController
// 1.在一个方法中定义,在另外一个方法调用
// 2.在一个类中定义,在另外一个类中调用
- (void)viewDidLoad {
[super viewDidLoad];
void(^block)() = ^{
NSLog(@"调用block");
};
_block = block;
}
//在另外一个类或者另外一个方法调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// block调用:就去寻找保存代码,直接调用
if (_block){
_block();
}
}
2. block传值
主动方声明block、调用block,被动方实现block,然后对传过来的值进行使用,代码如下:
SecodViewController.m文件的代码:
//1. 声明block
@property (nonatomic, copy) void(^block)(NSString *text);
if (_block) {
//2. 调用block
_block(textField.text);
}
FirstViewController.m文件的代码:
SecodViewController *svc = [[SecodViewController alloc]init];
UILabel *label = (id)[self.view viewWithTag:10];
//3. 实现block
void(^aBlock)(NSString *text) = ^(NSString *text){
label.text = text;
};
// 实现的block指向声明的block
svc.block = aBlock;
三. block底层结构
可参考:
iOS-block1-底层结构、变量捕获、类型
iOS-block2-copy操作、对象类型的auto变量、__block
iOS-block3-__block变量的内存管理、__forwarding、__block修饰的对象类型、循环引用
四. 小知识点
- 只有MRC才能调用[super dealloc];
- 只有MRC才能调用retain、release。
- ARC管理原则:只要一个对象没有被强指针指向就会被销毁。默认局部变量对象都是强指针,存放到堆里面。
- MRC没有strong、weak,局部变量对象就是相当于基本数据类型,在栈里面。
- MRC给成员变量赋值,一定要使用set方法,不能直接访问下划线成员变量进行赋值,因为MRC的set方法里面有retain和release操作,不然会造成内存泄漏,如下:
- (void)setName:(NSString *)name {
if (name != _name) {
[_name release];
_name = [name retain];
}
}
网友评论