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

  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/huangzs/p/10984034.html
Copyright © 2011-2022 走看看