iOS-block

2020-08-11  本文已影响0人  Imkata

一. 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. 注意点

  1. 如果没有参数,参数可以省略。
void(^block1)() = ^{
    NSLog(@"调用了block1");
};
  1. 如果有参数,定义的时候,必须要写参数,而且必须要有参数变量名。
void(^block2)(int) = ^(int a){
    NSLog(@"%d,a);
};
  1. 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修饰的对象类型、循环引用

四. 小知识点

  1. 只有MRC才能调用[super dealloc];
  2. 只有MRC才能调用retain、release。
  3. ARC管理原则:只要一个对象没有被强指针指向就会被销毁。默认局部变量对象都是强指针,存放到堆里面。
  4. MRC没有strong、weak,局部变量对象就是相当于基本数据类型,在栈里面。
  5. MRC给成员变量赋值,一定要使用set方法,不能直接访问下划线成员变量进行赋值,因为MRC的set方法里面有retain和release操作,不然会造成内存泄漏,如下:
- (void)setName:(NSString *)name {
    if (name != _name) {
        [_name release];
        _name = [name retain];
    }
}
上一篇 下一篇

猜你喜欢

热点阅读