iOS-block

作者: Imkata | 来源:发表于2020-08-11 08:23 被阅读0次

    一. 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];
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS-block

          本文链接:https://www.haomeiwen.com/subject/nhkjdktx.html