iOS Developer

Block的使用

2017-04-06  本文已影响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];
        }];
    }

}];
上一篇 下一篇

猜你喜欢

热点阅读