zoukankan      html  css  js  c++  java
  • iOS开发-多层嵌套block中如何使用__weak和__strong

    1、关于__weak
    __weak只能在ARC模式下使用,也只能修饰对象(比如NSString等),不能修饰基本数据类型(比如int等)
    __weak修饰的对象在block中不可以被重新赋值。
    __weak只在ARC下使用,可以避免循环引用。
    __weak修饰对象不会增加引用

        __weak __typeof(self) weakSelf = self;

        self.testBlock = ^{

            [weakSelf doSomeThing];

        });


    弱引用不会影响对象的释放,但是当对象被释放时,所有指向它的弱引用都会自定被置为 nil,这样可以防止野指针。

    2、关于__block
    __block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
    在MRC下使用__block是可以避免循环引用的;
    在ARC下使用 __block typeof(self)weakSelf = self;因为block是用过添加引用来访问实例变量的,所以self会被retain一次,block也是一个强引用,会引起循环引用。

    __block修饰对象会增加引用

    3、关于 __strong

    - (void)viewDidLoad {

        [super viewDidLoad];

        

        MyOBJ *mm = [[MyOBJ alloc]init];

        mm.name = @"Lilei";

        __weak typeof(student) weakSelf = mm;

        

        mm.doBlock = ^{

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                NSLog(@"my name is = %@",weakSelf.name);

            });

        };

        

        mm.doBlock();

    }

    //输出:my name is = (null)


    在dispatch_after这个函数里面。在doBlock()的block结束之后,mm被自动释放了。
    又由于dispatch_after里面捕获的__weak的mm,在原对象释放之后,__weak对象就会变成nil,防止野指针。

    那么我们怎么才能在weakSelf之后,block里面还能继续使用weakSelf之后的对象呢?

    究其根本原因就是weakSelf之后,无法控制什么时候会被释放,为了保证在block内不会被释放,需要添加__strong。

    在block里面使用的__strong修饰的weakSelf是为了在函数生命周期中防止self提前释放。strongSelf是一个自动变量当block执行完毕就会释放自动变量strongSelf不会对self进行一直进行强引用。

    - (void)viewDidLoad {

        [super viewDidLoad];

        

        MyOBJ *mm = [[MyOBJ alloc]init];

        

        mm.name = @"Hanmeimei";

        __weak typeof(mm) weakSelf = mm;

        

        mm.doBlock = ^{

            __strong typeof(mm) strongSelf = weakSelf;

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                NSLog(@"my name is = %@",strongSelf.name);

            });

            

        };

        

        mm.doBlock();

    }

    //输出:my name is = Hanmeimei

    weakSelf 是为了block不持有self,避免Retain Circle循环引用。
    在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。

    strongSelf的目的是因为一旦进入block执行,假设不允许self在这个执行过程中释放,就需要加入strongSelf。block执行完后这个strongSelf 会自动释放,不会存在循环引用问题。
    如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

    4、关于 多层嵌套的block
    4.1单层block

    - (void)doSomething{

        XXModel *model = [XXModel new];

        

        __weak typeof(self) weakSelf = self;

        

        model.dodoBlock = ^(NSString *title) {

            

            __strong typeof(self) strongSelf = weakSelf;

            strongSelf.titleLabel.text = title;

        };

        

        self.model = model;

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        [self doSomething];

    }


    4.2双层block

    - (void)setUpModel{

        XXModel *model = [XXModel new];

        

        __weak typeof(self) weakSelf = self;

        

        model.dodoBlock = ^(NSString *title) {

            

            __strong typeof(self) strongSelf = weakSelf;//第一层

            strongSelf.titleLabel.text = title;

            

            __weak typeof(self) weakSelf2 = strongSelf;

            strongSelf.model.dodoBlock = ^(NSString *title2) {

                

                __strong typeof(self) strongSelf2 = weakSelf2;//第二层

                strongSelf2.titleLabel.text = title2;

            };

        };

        

        self.model = model;

    }


    这样就避免的引用循环,不管都多少个block嵌套,都可以按照这样来做。

    转自:https://blog.csdn.net/nathan1987_/article/details/82749057

  • 相关阅读:
    Java生鲜电商平台-服务化后的互联网架构实战(针对生鲜电商小程序或者APP)
    你有一份新的C++书单,请注意查收!
    想了解大数据的鼻祖Hadoop技术栈,这里有一份优质书单推荐!
    程序员的健康问题终于有救了,有个资深程序员写了本《程序员健康指南》!
    《程序员如何优雅地挣零花钱》电子书免费开源!!!
    学习设计模式,你需要这样一份书单!
    《自拍教程36》段位三 Python面向对象类
    《自拍教程35》段位二 Python面向过程函数
    《自拍教程34》段位一 Python批处理脚本
    《自拍教程33》案例篇 内容介绍
  • 原文地址:https://www.cnblogs.com/huangzs/p/10984034.html
Copyright © 2011-2022 走看看