美文网首页iOS专题资源__系统知识点iOS Review内功修炼
iOS 代理为啥要用weak修饰? (刨根问底一)

iOS 代理为啥要用weak修饰? (刨根问底一)

作者: 汉斯哈哈哈 | 来源:发表于2015-08-14 16:55 被阅读17817次

在开发中我们经常使用代理,或自己写个代理,而代理属性都用weak(assign)修饰,看过有些开发者用strong(retain),但并没发现有何不妥,也不清楚weak(assign)与strong(retain)修饰有何区别

功能实现就行了,考虑这么多干嘛~~~我只能哈哈哈

  • weak:指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制
@property (nonatomic, weak) id<HSDogDelegate>delegate;
  • strong该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用(Retain Cycles)
@property (nonatomic, strong) id<HSDogDelegate>delegate;

可能你还不太理解,没关系,下面先举例,看结果,再分析!

举例

  • HSDog类

HSDog.h:

@protocol HSDogDelegate <NSObject>
@end

@interface HSDog : NSObject

@property (nonatomic, weak) id<HSDogDelegate>delegate;

@end

HSDog.m:

#import "HSDog.h"

@implementation HSDog

- (void)dealloc
{
    NSLog(@"HSDog----销毁");
}

@end
  • HSPerson类

HSPerson.h:

@interface HSPerson : NSObject

@end

HSPerson.m:

#import "HSPerson.h"
#import "HSDog.h"

@interface HSPerson()<HSDogDelegate>
/** 强引用dog*/
@property (nonatomic, strong) HSDog *dog;
@end

@implementation HSPerson

- (instancetype)init
{
    self = [super init];
    if (self) {
        // 实例化dog
        self.dog = [[HSDog alloc] init];
        // dog的delegate引用self,self的retainCount,取决于delegate修饰,weak:retainCount不变,strong:retainCount + 1
        self.dog.delegate = self;

    }
    return self;
}

- (void)dealloc
{
    NSLog(@"HSPerson----销毁");
}

@end
  • 在ViewController实现
#import "ViewController.h"
#import "HSPerson.h"

@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // 实例化person, self对person弱引用,person的retainCount不变
    HSPerson *person = [[HSPerson alloc] init];

}
@end

结果

  • weak修饰代理
@property (nonatomic, weak) id<HSDogDelegate>delegate;

运行->打印

HSPerson----销毁
HSDog----销毁
  • strong修饰代理
@property (nonatomic, strong) id<HSDogDelegate>delegate;

运行->打印
....并未打印,说明HSPerson、HSDog对象没调用dealloc方法,两个对象未销毁
这也是我们经常说的内存泄露,该释放的内存并未释放!

分析

  • 使用strong

person对dog强引用

@property (nonatomic, strong) HSDog *dog; person

self.dog.delegate又对person强引用,使person的retainCount + 1

@property (nonatomic, strong) id<HSDogDelegate>delegate;

当viewController不对person引用后,dog.delegate对person还强引用着,person的retainCount为1,所以person不会释放,dog固然也不会释放,这就是造成循环引用的导致内存泄露的原因!

  • 使用weak

person对dog强引用

@property (nonatomic, strong) HSDog *dog; person

self.dog.delegate只对person弱引用,并未使person的retainCount + 1

@property (nonatomic, weak) id<HSDogDelegate>delegate;

所以当viewController不对person引用后,person的retainCount为0,即person会被释放,那么dog也被释放

文章同步到微信公众号:hans_iOS 有疑问可以在公众号里直接发

相关文章

  • iOS 代理为啥要用weak修饰? (刨根问底一)

    在开发中我们经常使用代理,或自己写个代理,而代理属性都用weak(assign)修饰,看过有些开发者用strong...

  • iOS中代理属性为什么要用Weak修饰?

    iOS中代理属性为什么要用Weak修饰? 一.写在前面 代理设计模式,在iOS开发过程中,是一个非常常见的设计模式...

  • assgin和weak区别

    面试必备。 ARC才有weak。 weak只能修饰对象类型,主要用控件及代理,而assign使用于修饰基本类型的。...

  • iOS 为什么要用weak修饰代理(delegate

    在开发中我们经常使用代理,或自己写个代理,而代理属性都用weak(assign)修饰,看过有些开发者用strong...

  • iOS 为什么要用weak修饰代理(delegate)

    最近在review自己之前的代码发现了循环引用,ViewController和View相互持有的的问题,经层层排除...

  • ios面试

    delegate 为啥assign weak修饰 一般使用代理都会设置控制器为代理,在内存管理角度说引用计数会加...

  • 一.代理为什么要用weak修饰

    代理为什么要用weak修饰 在说这个之前,得了解一个知识点, view 的属性和控制器是用ratain修饰的强引用...

  • NSURLSession对代理的强引用

    一般来说,在ARC下修饰delegate要用weak而不是strong 用tableview的代理(viewcon...

  • IOS

    一、Delegate为什么要用weak或者assign修饰,不能用strong?说明:weak、assign修饰的...

  • 2016笔记——Leaks

    Instrument如此强大,为何不好好使用呢? 先来看看前几天就代理展开的讨论(代理为什么要用weak修饰)。 ...

网友评论

  • 英俊神武:不能写个demo吗
    龙子陵:人家都写得这么明白了还要demo?
  • Levi段玉磊:如果经常循环引用导致iOS内存泄漏,这样的话,我们有其他方法来排查内存泄漏么?我能想到的就是通过每个页面打印 dealloc 日志。
    胖子程:静态分析Analyze、Instrument、MLeaksFinder各种手段可以查到
  • Cocoa丶:@汉斯 你好,之前看过你的几篇文章。今天遇到你说,或者大多说人都说用strong修饰代理是会造成循环引用!但是据我所看到的用strong修饰代理的地方出现在:AFNetWorking,还有一些苹果的官方库(具体什么库,我给忘记了),在此我并非无的放矢,只是暂时还没搞明白为什么会有如此现象。希望能与你一起探讨。
  • ce70df11c8e3:兄弟,写得好 我顶你
  • Accepted_:有个小小的笔误

    举例

    HSDog类
    HSDog.h:
    HSDog.m: 这里写成了HSPerson.m啦
    汉斯哈哈哈:@牛序序 :smile:
    Accepted_:@汉斯哈哈哈 :blush: 主要比较菜,需要一行一行一句一句的读 哈哈
    汉斯哈哈哈:@牛序序 这都被你发现:relaxed:
  • 3e8eb14bdf82:写得真好,没白看
  • sea777777:感谢分享
  • wokenshin:我想问一下,如果我的一类是用的单例呢?这种情况下 使用weak 和 strong有什么区别吗?
  • bing_feng_lv:只要搞懂了set方法是怎么赋值的,也就能分析出循环引用产生的原因
  • 8a44cbc27446:// 实例化person, self对person弱引用,person的retainCount不变
    HSPerson *person = [[HSPerson alloc] init];
    为什么说是弱引用呢,这里都没有用到self.person之类的啊
  • wg689:看明白了 不错
  • 古斯比德:赞一下好文,好好学习了:clap::clap::+1:
    汉斯哈哈哈:@古斯比德 :smile:
  • 80c9a4518c6f:又有了进一步了解
  • 08e367b3e25e:谢谢分享
  • 韦韦韦:若果 dog 不是一个强引用呢(不是设置代理的属性)?是不是不需要weak了。
    handyTOOL:@韦韦韦 dog如果是weak,new完就会被释放了:grin:
  • doubleJJ:第一遍看不是很理解,看第二次就明白了,感谢分享
  • 超_iOS:那么请教楼主,何时用assin何时用weak啊,我一般都用的assin
    汉斯哈哈哈:@李二超 不同点:

    1.weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。

    2.assigin 可以用非 OC 对象,而 weak 必须用于 OC 对象
    来自:微博iOS程序犭袁
  • TIME_for:用assgin,和用weak修饰delegate有什么区别呢?
    HenryCheng:@Toyun :grin: :grin: :grin:
    TIME_for:@HenryCheng OK,明白了,Thanks~~
    HenryCheng:@Toyun assign是指针赋值,不对引用计数进行操作,如果使用完毕以后,不把其置为nil,就有可能产生野指针,这时候如果操作不会crash,而weak使用完就没有了,所以weak更安全,其他也没啥区别
  • Somerr态:强迫症还是要说一下,最后一张图的weak弱引用Person还是要画个虚线箭头😂
  • 7cd363b098c9:强迫症还是要说一下,最后一张图的weak弱引用Person还是要画个虚线箭头😂
  • 7cd363b098c9:好文章,多谢分享!
  • 麦子_today:好文章,感谢分享
  • 75040dae73e8:哥们辛苦了,这个东西学的时候一直没闹懂,刚刚在地铁上花了15分钟懂了,谢谢分享。
    汉斯哈哈哈:@C己 加油:grin:
  • 自由在心:苹果h文件里都是使用assign修饰,那么问题来了,使用weak 和assign 有什么区别? weak修饰的对象释放后其所修饰的变量会被置为nil, 而assign 好像什么也不会做只是简单的赋值,也就是说assgin修饰的变量指针还是指向那个地址(不管这个地址空间的对象是否释放),那么这样assign修饰的delegate 不是更不合理吗?可apple是这样用,有其它别的考虑吗?
    986d14688d75:@SunT_孙涛 这是我们15期的涛桑么 :smiley:
    自由在心:@SunT_孙涛 你说的我知道,只是在疑问苹果API里的delegate是用assign的原因,现在的delegate已经改成weak了,苹果遗留问题。
    HQQ_哈球球:@自由在心 assgin 在引用计数=0 的时候,不会自动置为nil . weak 会自动置为nil
  • 天下无贼:说的确实很容易懂,很赞的文章
  • 8d7e10a4eeee:讲解得挺精辟的 看了以后我懂了
  • 康大侠:HSPerson *person = [[HSPerson alloc] init];这个是强引用,ARC自动release了,alloc会使得引用计数加一
    GerryZhu:@康大侠 你确定 不是 alloc、copy、new?
    然然啊:@康大侠 请问下为啥这个是强引用呢?就是不明白这里
  • eb3179e35abc:其实就是循环引用的问题
    buzaixian程序员:怎么个循环引用呢?了解一下:heart_eyes:
    十一岁的加重:@eb3179e35abc 四字概括全文,经典
  • e5b69d879f27:关注一下,搞Android的,最近开始学习iOS,看到这一块儿了也是不懂,看了你的还是不是太懂,先收藏了吧。另外问问,是不是现在的项目都是使用arc了呀
    汉斯哈哈哈:@简约书适 嗯,新项目基本都用arc
  • ba08449e08cf:虽然看不懂,为你的用心和专业点赞。😋
    汉斯哈哈哈:@丘丘123 谢谢 :stuck_out_tongue_winking_eye:

本文标题:iOS 代理为啥要用weak修饰? (刨根问底一)

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