美文网首页
iOS block 理解

iOS block 理解

作者: 笔寂晓才 | 来源:发表于2016-01-20 15:14 被阅读148次

    1、Block生命周期:

    int (^square) (int) = ^(int a ) {return a*a ;};
    int result = square(5);

    block一开始都是被放到stack,其生命周期随着method或function结束就会被回收,和一般变量的生命周期一样。

    对于局部变量,block会把它copy下来,放在stack中。所以在后面的过程中修改局部变量的值,不会影响block的执行结果。如果block中使用的变量是 static 或者 指针 或者 __block ,修改才会影响结果。

    [inBlock copy]的值就會被放到heap,就可以一直使用。但是-copy指令是为了要把block 从stack搬到heap,与原变量是有区别的。

    2、解决循环引用:

    最简单的方法就是使用带参数的block,参数会被复制到block的作用域。
    如果想要修改变量的值,在变量申明前加 __block 使其被锁定,不再是局部变量

    NSString *make = @"Honda"; NSString *(^getFullCarName)(NSString *) = ^(NSString *model) { return [make stringByAppendingFormat:@" %@", model]; }; NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord

    多个参数的形式
    NSString *(^getFullCarName)(NSString *,NSString *)= ^(NSString *model,NSString *mod) { ...... };

    如果是系统提供的方法,无法修改block形式的:
    __weak __typeof(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; if(strongSelf != nil) { [strongSelf doSomething]; [strongSelf doOtherThing]; } });

    首先,在 block 之前定义对 self 的一个弱引用 weakSelf,因为是弱引用,所以引用指数不会加1,但是当 self 被释放时 weakSelf 会变为 nil;在 block 中引用该弱应用,通过使用强引用 strongSelf 来引用该弱引用,这时如果 self 不为 nil 就会 retain self,这样可以防止在后面的使用过程中 self 被其他地方释放;然后在之后的 block 块中使用该强引用 strongSelf,注意在使用前要对 strongSelf 进行了 nil 检测,因为多线程环境下在用弱引用 weakSelf 对强引用 strongSelf 赋值时,弱引用 weakSelf 可能已经为 nil 了。如果self是nil的话,一些情况下会crash。

    __strong 确保在 Block 内strongSelf 不会被释放。

    3、总结:

    block会把变量copy到stack中,所以对变量的修改不会影响到heap上的数据。
    如果要修改生效加__block,把变量锁定到heap上。
    注意block里面的循环引用,主要就是self需要weak。
    facebook的pop中是通过把self当做参数传递进去的。

    相关文章

      网友评论

          本文标题:iOS block 理解

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