美文网首页Objective-C学习手册iOS学习笔记iOS学习开发
代理模式中delegate属性为assign的原因

代理模式中delegate属性为assign的原因

作者: Bestmer | 来源:发表于2016-08-08 20:52 被阅读238次

    前言

    在代理模式中,属性通常写成如下形式

    @property (nonatomic, assign) id<实现的某个协议名称>delegate;
    

    究其背后的原因为什么不使用retain来修饰,其实这里涉及到了内存管理中的循环引用问题。

    举个例子

    • 对象a创建并引用了对象b
    • 对象b创建并引用了对象c
    • 对象c创建并引用了对象b

    此时b的引用计数为2,a和c的引用计数为1

    • 假设a不在使用b,调用release释放了b
    • 因为c还在使用b,所以b得引用计数为1,b不会被释放
    • 而此时c的引用计数为1,也不会被释放
    • 从此,b和c永远留在了内存中,造成了内存泄漏。
    • 所以,针对这种情况,我们要避免循环引用,这就是为什么代理模式中属性使用assign而不是retain的根本原因。

    在举个例子

    • 先创建两个类,Baby和Nanny
    • Baby.h
      • Baby里写了一个协议
      • 有一个代理属性
    • Baby.m
      • 假设用retain修饰的情况
      • 并重写了delegate的setter and getter

    • Nanny.h
      • Nanny里有一个Baby属性
    • Nanny.m
      • 重写了Baby的setter and getter
      • 为了方便分析问题

    • main.h

    分析

    • 根据内存管理的原则,谁持有对象,那谁就有责任将其释放
    • 当各自的引用计数由1到0时,会调用dealloc方法。
    • 但是他们此时他们互相持有,导致最后谁都得不到释放。

    • 过度释放

    总结

    希望通过这个例子,能让大家对于内存管理有更深刻的理解。

    相关文章

      网友评论

        本文标题:代理模式中delegate属性为assign的原因

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