美文网首页OC 底层原理笔记
11 block-循环引用详解

11 block-循环引用详解

作者: zysmoon | 来源:发表于2020-01-20 14:41 被阅读0次
循环引用问题
1653926-54f6d705c5a184a6.png

循环引用代码例子如下

#import <Foundation/Foundation.h>

typedef void(^CSBlock)(void);
@interface Person : NSObject
/** age*/
@property(nonatomic,assign)int age;
/** blokc*/
@property(nonatomic,copy) CSBlock block;
@end

@implementation Person
- (void)dealloc {
    NSLog(@"%s",__func__);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.age = 100;
        person.block = ^{
            NSLog(@"age = %d",person.age);
        };
    }
    NSLog(@"end");
    return 0;
}

运行结果如下

1653926-08107db4bcb969d2.png
解决循环引用问题 - ARC
  • 用__weak、__unsafe_unretained解决
    • __weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil
    • __unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变
1653926-6a60dc36706807c7.png

[图片上传中...(1653926-15dd8d8892a980c9.png-f61152-1542180021728-0)]

代码佐证

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // __weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil
        // __unsafe_unretained:不会产生强引用,不安全,指向的对象销毁时,指针存储的地址值不变

        Person *person = [[Person alloc] init];
        person.age = 100;
//        __weak typeof(person) weakPerson = person;
        __unsafe_unretained typeof(person) weakPerson = person;
        person.block = ^{
            NSLog(@"age = %d",weakPerson.age);
        };
    }
    NSLog(@"end");
    return 0;
}

  • 用__block解决(必须要调用block)
1653926-15dd8d8892a980c9.png

代码佐证

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       // 法三 __block
        __block Person *person = [[Person alloc] init];
        person.age = 10;
        person.block = ^{
            NSLog(@"age is %d", person.age);
            person = nil;
        };
        person.block();
    }
    NSLog(@"end");
    return 0;
}

运行结果

1653926-2cf37154fc773ee4.png
解决循环引用问题 - MRC
  • 用__unsafe_unretained解决(MRC环境下不支持__weak)
1653926-7cbc0749490c19e4.png
  • 用__block解决
1653926-8938b5b745933ed7.png

代码例子佐证

int main(int argc, const char * argv[]) {
    @autoreleasepool {
         // MRC环境下
        // MRC不支持__weak的
        __block Person *person = [[Person alloc] init];
        person.age = 10;
        person.block = ^{
            NSLog(@"age is %d", person.age);
        };
        [person release];
    }
    NSLog(@"end");
    return 0;
}

运行结果如下

1653926-b8c895e256ef066c.png

面试题 - Block

block的原理是怎样的?本质是什么?

封装了函数调用以及调用环境的OC对象

__block的作用是什么?有什么使用注意点?

详情请看iOS-block底层原理详解之__block属性

block的属性修饰词为什么是copy?使用block有哪些使用注意?
  • block一旦没有进行copy操作,就不会在堆上
  • 使用注意:循环引用问题
block在修改NSMutableArray,需不需要添加__block?
  • 不需要

本文参考:
路飞_Luck (https://www.jianshu.com/p/07f7b96bb03f)
以及借鉴MJ的教程视频
非常感谢.


项目演示代码
iOS-block-cycle

相关文章

  • 11 block-循环引用详解

    循环引用问题 循环引用代码例子如下 运行结果如下 解决循环引用问题 - ARC 用__weak、__unsafe_...

  • 2022-04-19 iOS计时器引用解除问题

    我们使用NSTimer的时候,经常发生循环引用 以上代码产生循环引用环,self->timer->block->s...

  • block-循环引用

    block的循环引用,在日常开发中,我们常常遇到,但是可能部分新人还不太了解为何会循环引用,到底是如何循环引用理解...

  • iOS-底层原理(11)-block-循环引用详解

    循环引用问题 循环引用代码例子如下 运行结果如下 解决循环引用问题 - ARC 用__weak、__unsafe_...

  • iOS块语法block-循环引用

    Block简介 Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事。需要注意...

  • Block循环引用详解

    前言 在项目中经常用到block,使用不当就很容易因为循环引用而造成内存泄漏。本文分析了block循环引用形成原因...

  • swift 循环引用详解

    类实例之间的循环强引用 下面展示了一个不经意产生循环强引用的例子。例子定义了两个类:Person和Apartmen...

  • block详解<4>: 循环引用

    这个问题网上的文章实在是太多,我就大概介绍一下就好了。先看一下循环引用的例子: 上面的VC2是从前面push进来的...

  • 4-8 循环引用

    3种循环引用 自循环引用 相互循环引用 多循环引用 Block的循环引用 NSTimer 的循环引用 破除循环引用...

  • 右值引用

    参考资料 谈谈 C++ 中的右值引用C++11 左值、右值、右值引用详解

网友评论

    本文标题:11 block-循环引用详解

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