首页 > 代码库 > Block

Block

 

Block的实质是Objective-C的对象

1. Block的使用

Block的使用其实相当于代理,一般是跨越两个类来使用的。比如作为property属性或者作为方法的参数,这样就能跨越两个类了(参考:“Block全面分析”)

如下为声明为property属性的方法

typedef void (^blk_t)(void);
@property (nonatomic, copy) blk_t blk;

2.__block关键字的使用

- (void)viewDidLoad
{
    //将Block定义在方法内部
    int x = 100;
    void (^sumXAndYBlock)(int) = ^(int y){
    x = x+y;
    printf("new x value is %d",x);
    };
    sumXAndYBlock(50);
}

上面在block内对x进行赋值,会提示错误,需要把x的声明改为如下:

__block int x = 100;

3. 截获自动变量

int main() {
    int dmy = 256;
    int val = 10; 
    const char *fmt = "val = %d\n"; //编译后 bound by copy 
     void (^blk)(void) = ^{printf(fmt,val);}; //在此截获,后面调用时调用的是此处的值 
    val = 2;
    fmt = "These values were changed. val = %d\n";
    blk();
    return 0; 
}

(1)所谓“截获自动变量值”意味着在执行Block语法时,Block语法表达式所使用的自动变量值被保存到Block的结构体实例(即Block自身__main_block_impl_0)中。

(2)Block不能截获C语言数组类型的自动变量。

 (3)Block中使用自动变量后,在Block的结构体实例中重写该自动变量也不会改变原先截获的自动变量(实现上)。

4. 避免循环引用

   @weakify(self);
    [[MTANetworkManager instance] addResMiddleware:^(id object, MTAMiddlewareNextBlock next) {
        @strongify(self);
            [self refreshTokenWithTask:task];
    }];

上面的代码中,self拥有block,block中又使用了self,因此需要使用@weakify(self)和@strongify(self)来避免循环引用。

原理(参考“strongify & weakify”):

After @strongify is called, self will have a different pointer address inside the block than it will outside the block. That‘s because @strongify declares a new local variable called self each time. (This is why it suppresses the -Wshadow warning, which will “warn whenever a local variable shadows another local variable.”) It‘s worth reading and understanding the implementation of these functions. So even though the names are the same, treat them as separate strong references.

However, remember that after your first use of @strongify, self will refer to local, stack variables

 

Block