Block实现

作者: RichMartin | 来源:发表于2017-10-25 16:21 被阅读1次
        
        // block声明:返回值(^block变量名)(参数)
        void(^block)();
        
        // block定义:三种方式 = ^(参数){};
        // 第一种
        void(^block1)() = ^{
            NSLog(@"调用了block1");
        };
        
        // 第二种 如果没有参数,参数可以隐藏,如果有参数,定义的时候,必须要写参数,而且必须要有参数变量名
        void(^block2)(int) = ^(int a){
            
        };
        
        // 第三种 block返回可以省略,不管有没有返回值,都可以省略
        int(^block3)() = ^int{
            return 3;
        };
        
        
        // block类型:int(^)(NSString *)
        int(^block4)(NSString *) = ^(NSString *name){
            return 2;
        };
        
        // block调用
        block1();
        
        // block快捷方式 inline
    //    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
    //        <#statements#>
    //    };
    

    // 返回一个block方法 并调用

    - (void(^)())test
    {
        return ^{
            NSLog(@"调用了block");
        };
    }
    
    调用: self.test();
    
    

    链式编程思想:把所有的语句用.号连接起来,好处:可读性非常好 (类似Masonry) make.center.equalTo(ws.view);)
    需求:封装一个计算器,提供一个加号方法

     .h
     
    @property (nonatomic, assign) int result;
    
    - (CalculatorManager *(^)(int))add;
    
    
    .m
     - (CalculatorManager *(^)(int))add
    {
        return ^(int value){
            _result += value;
            
            return self;
        };
    }
    

    调用方式:

     CalculatorManager *mgr = [[CalculatorManager alloc] init];
     mgr.add(5).add(5).add(5).add(5);
     NSLog(@"%d",mgr.result);
    

    如果不需要返回self 可类似:返回一个block方法实现

    - (CalculatorManager *)add:(int)value
    {
        _result += value;
        
        return self;
    }
    
    调用:
     CalculatorManager *mgr = [[CalculatorManager alloc] init];
     [[[[[mgr add:5] add:5] add:5] add:6] add:7];
      NSLog(@"%d",mgr.result);
    

    循环引用

    @property (nonatomic, strong) void(^block)();
    
      // block造成循环利用:Block会对里面所有强指针变量都强引用一次
        
        __weak typeof(self) weakSelf = self;
        
        _block = ^{
    //        NSLog(@"%@",weakSelf);
            __strong typeof(weakSelf) strongSelf = weakSelf;
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                
                 NSLog(@"%@",strongSelf);
                
            });
            
        };
        
        _block();
    

    // 如果是局部变量,Block是值传递
    // 如果是静态变量,全局变量,__block修饰的变量,block都是指针传递

       static int a = 3;
       __block int a = 3;
        void(^block)() = ^{
            
            NSLog(@"%d",a);
            
        };
        
        a = 5;
        
        block();
    

    输出都为:5

    block是不是一个对象?
    是一个对象

    如何判断当前文件是MRC,还是ARC
    1.dealloc 能否调用super,只有MRC才能调用super
    2.能否使用retain,release.如果能用就是MRC
    
    ARC管理原则:只要一个对象没有被强指针修饰就会被销毁,默认局部变量对象都是强指针,存放到堆里面
    
    MRC了解开发常识:1.MRC没有strong,weak,局部变量对象就是相当于基本数据类型
                  2.MRC给成员属性赋值,一定要使用set方法,不能直接访问下划线成员属性赋值
    
    总结:只要block没有引用外部局部变量,block放在全局区
    
    MRC:管理block
            只要Block引用外部局部变量,block放在栈里面.
            block只能使用copy,不能使用retain,使用retain,block还是在栈里面
    
    
    ARC:管理block
        只要block引用外部局部变量,block放在堆里面
        block使用strong.最好不要使用copy

    相关文章

      网友评论

        本文标题:Block实现

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