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