Block的使用

作者: 老骚鹅 | 来源:发表于2017-04-06 16:15 被阅读69次

http://www.jianshu.com/p/f4fa7aeb2035

一般说的block无法改变局部变量,必须加__block才可以

准确的说是无法改变局部变量的地址,如果该局部变量是一个Student类的对象,你无法再block中将其=nil,但是可以修改.name属性.因为=nil时其实是改变了他的内存地址,而修改.name不会改变内存地址

__weak typeof(self) mv=self;正常是这样

=================================

MASonry中使用self不需要弱引用 网络封装中也不需要弱引用

MJRefresh中必需要弱引用)

ATTNetWork中successBlock和faildBlock出现Self不需要弱引用.. 正确是ATTNetWork强引用Self,所以当在VC中请求还没完成,然后pop退出当前VC,会造成VC先不释放,等到Success或者faild的时候,执行完successBlock或者faildBlock之后VC才会销毁 如果

=================================

如果在myBlock中嵌套my2Block
self.testView.myBlock = ^{

NSLog(@"shuchu1");

test2View.my2Block = ^{

self;

NSLog(@"shuchu2");

};

};
那么self.testView会强引用test2View,也会强引用self,test2View会强引用self

==============================

解决 retain circle

Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。

示例代码:


1 __weak __typeof__(self) weakSelf = self;

2    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

3    [weakSelf doSomething];

4 });

clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:

1 __weak __typeof__(self) weakSelf = self;

2    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

3    [weakSelf doSomething];

4    [weakSelf doOtherThing];

5 });

在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:

1 __weak __typeof__(self) weakSelf = self;

2    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

3    __strong __typeof(self) strongSelf = weakSelf;

4    [strongSelf doSomething];

5    [strongSelf doOtherThing];

6 });

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

总结

在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。

如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

-------------------------------分割线---------------------------------------------

以上内容知道了我们为什么要用weakSelf和strongSelf, 为了简单实用一般会定义成宏weakify和strongify,如下:

View Code

使用过RAC的同学应该都知道@weakify和@strongify,这两个宏在RAC中是已经定义好的,可以直接用,属于比较牛逼的写法。这两个宏一定成对出现,先@weakify再@strongify.可以很好的管理Block内部对self的引用。可以一步步点开发现其实使用到了C语言中的组合运算符。

1 @weakify(self);

2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

3      @strongify(self);

4      [self doSomething];

5      [self doOtherThing];

6  });

block中如果用了下划线_的形式,其实用@weakify(self) 和@strongify(self)其实还是不行的

=====================================

看下面的例子:block中套block要这样写才不会循环引用

@weakify(self);
[[ATTNetwork shareInstance]getWithURL:GetHotListURL token:nil params:params success:^(id response) {

    @strongify(self);
    
} failure:^(NSError *error) {
    @strongify(self);

        @weakify(self);
        [self.backView showNoNetWorkWithTryAgainBlock:^{
            @strongify(self);
            [self loadDataFromCache:NO];
        }];
    }

}];

相关文章

  • ios block使用

    iOS Block的使用一 .最简单的block使用******使用block的三个步骤:1.定义block变量 ...

  • 白话block

    本文内容 什么是block? block的用途 block的用法 block在使用中遇到的问题 如何使用xcode...

  • iOS Block使用注意

    block本质是两个结构体,使用block使代码简单易读。使用Block注意: 1、block内部使用外部指针,会...

  • iOS Block -浅析 文章

    Block 的使用有两种:1.独立Block 。2.内联Block 。 《一》独立Block 使用方式 一、定义一...

  • OC中的block回顾

    1.block声明 2.block的typedef 2.1 typedef的使用 2.2 声明block类型的使用...

  • Block其实很简单

    Block的几种情况 block的使用 1.使用block实现反向传值 2.利用block写响应式编程的技巧

  • Objective-C 类之间通信

    block的使用 block的定义和使用 变量的作用域及代码的执行顺序 block外部变量的值在block内部具有...

  • Blocks

    使用block修改器 __block

  • iOS开发--当Block、代理、通知遇到女朋友

    什么是Block? 为什么使用Block? 怎么使用Block? 本文将从这三个问题入手来逐渐了解Block。 本...

  • block使用及其底层原理

    一 block基本使用 二 block底层结构 三 block变量捕获 四 block的类型 五 block对象类...

网友评论

    本文标题:Block的使用

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