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

前言

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

@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方法。
  • 但是他们此时他们互相持有,导致最后谁都得不到释放。

  • 过度释放

总结

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容