iOS - Delegate代理为什么要用weak修饰(面试官钟爱)
2017-06-24 13:42
471 查看
最近,我自己也是刚刚找到工作,也是面试了很多家公司。也尝试着总结一下,这是我的第一篇面试之后的总结,那么前戏不多,直奔主题,小伙们似乎已经等不及啦。
我们开发的过程中经常的使用代理delegate来替我们做事,而怎么修饰代理属性呢,说实话之前我还用过strong,却也一样实现功能,那时候我觉得有什么的,搞得出来都一样,想想都好笑。这个问题也是面试官的钟爱问题了。
现在,这里郑重庄严的说一下delegate一定用weak修饰!!!
下面,说一下原因:
weak:修饰对象只是指明该对象,并不负责保持这个对象,对象的销毁是由外部控制的。
strong:修饰对象是对该对象进行强引用,外界不能销毁该对象,会导致循环引用(Retain Cycles)
可能小白看到了不会懂,没关系,下面举个栗子。
首先创建一个LYSun类(LY是我骚气的名字),这是我的.h文件:
下面是.m文件:
然后创建一个LYPerson 类:
ViewController 的实现:
下面就是weak 和 strong 对比的结果:
weak修饰代理:
打印:
strong修饰代理:
并未有任何的打印,说明LYPerson、LYSun对象调用dealloc方法时,两个对象并没有销毁,这其实最容易产生内存泄漏,这两个对象申请的内存空间,用完之后并没有释放掉,仍然占用。
分析:
使用strong的情况如下:
当viewController不对person引用后想释放person的时候,发现这时sun.delegate对person还强引用着呢,person的retainCount为1,所以person不会释放,sun固然也不会释放,这就是造成循环引用导致的内存泄漏的原因。
使用weak修饰的情况如下:
那么,很显然了,当viewController 不对person引用之后,person的retainCount 为 0 ,当然可以释放啦,那么person就被释放了,sun也就被释放啦。
我们开发的过程中经常的使用代理delegate来替我们做事,而怎么修饰代理属性呢,说实话之前我还用过strong,却也一样实现功能,那时候我觉得有什么的,搞得出来都一样,想想都好笑。这个问题也是面试官的钟爱问题了。
现在,这里郑重庄严的说一下delegate一定用weak修饰!!!
下面,说一下原因:
weak:修饰对象只是指明该对象,并不负责保持这个对象,对象的销毁是由外部控制的。
@property (nonatomic, weak) id<LYSunDelegate>delegate;
strong:修饰对象是对该对象进行强引用,外界不能销毁该对象,会导致循环引用(Retain Cycles)
@property (nonatomic, strong) id<LYSunDelegate>delegate;
可能小白看到了不会懂,没关系,下面举个栗子。
首先创建一个LYSun类(LY是我骚气的名字),这是我的.h文件:
@protocol LYSunDelegate <NSObject> @end @interface LYSun : NSObject @property (nonatomic, weak) id<LYSunDelegate>delegate; @end
下面是.m文件:
#import "LYSun.h" @implementation LYSun - (void)dealloc { NSLog(@"LYSun----销毁"); } @end
然后创建一个LYPerson 类:
@interface LYPerson : NSObject @end
#import "LYPerson.h" #import "LYSun.h" @interface LYPerson()<LYSunDelegate> /** 强引用dog*/ @property (nonatomic, strong) LYSun *sun; @end @implementation LYPerson - (instancetype)init { self = [super init]; if (self) { // 实例化dog self.sun = [[LYSun alloc] init]; // sun的delegate引用self,self的retainCount,取决于delegate修饰,weak:retainCount不变,strong:retainCount + 1 self.sun.delegate = self; } return self; } - (void)dealloc { NSLog(@"LYPerson----销毁"); } @end
ViewController 的实现:
#import "ViewController.h" #import "LYPerson.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 实例化person, self对person弱引用,person的retainCount不变 LYPerson *person = [[LYPerson alloc] init]; } @end
下面就是weak 和 strong 对比的结果:
weak修饰代理:
@property (nonatomic, weak) id<LYSunDelegate>delegate;
打印:
LYPerson----销毁 LYSun----销毁
strong修饰代理:
@property (nonatomic, strong) id<LYSunDelegate>delegate;
并未有任何的打印,说明LYPerson、LYSun对象调用dealloc方法时,两个对象并没有销毁,这其实最容易产生内存泄漏,这两个对象申请的内存空间,用完之后并没有释放掉,仍然占用。
分析:
使用strong的情况如下:
//这个是LYPerson 类的属性,对 sun 强引用 @property (nonatomic, strong) LYSun *sun;
//这个是LYSun 类的代理属性 @property (nonatomic, strong) id<LYSunDelegate>delegate;
/* 在LYPerson.m 中self.sun.delegate 又对 self(就是person)请引用,person的retainCount + 1 */ self.sun.delegate = self;
当viewController不对person引用后想释放person的时候,发现这时sun.delegate对person还强引用着呢,person的retainCount为1,所以person不会释放,sun固然也不会释放,这就是造成循环引用导致的内存泄漏的原因。
使用weak修饰的情况如下:
//区别在于:delegate是weak修饰,所以这里self.sun.delegate对person是弱引用,所以person 的retainCount 不会+1 ,此时retainCount为0 self.sun.delegate = self;
那么,很显然了,当viewController 不对person引用之后,person的retainCount 为 0 ,当然可以释放啦,那么person就被释放了,sun也就被释放啦。
相关文章推荐
- iOS 为什么要用weak修饰代理(delegate)
- iOS开发-修饰代理delegate用weak还是assign?
- iOS中代理属性为什么要用Weak修饰?
- IOS:代理delegate为什么要用assign或者weak
- iOS中代理属性为什么要用Weak修饰?
- iOS 代理为啥要用weak修饰? (刨根问底一)
- iOS中delegate代理对象使用weak
- iOS 关于修饰代理用weak还是assign
- iOS 代理为啥要用weak修饰? (刨根问底一)
- iOS 代理修饰词weak 不用assgin
- iOS 关于修饰代理用weak还是assign
- iOS中delegate代理对象使用weak和assign哪个
- iOS 关于修饰代理用weak还是assign
- iOS内存管理(3)-- iOS 代理要用weak修饰
- delegate 作为属性,为什么要用weak修饰?
- delegate 作为属性,为什么要用weak修饰?
- iOS中delegate代理对象使用weak和assign哪个?
- iOS 关于修饰代理用weak还是assign
- iOS中代理属性用Weak修饰
- IOS开发--循环引用问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东