iOS

来源:互联网 发布:淘宝达人直播申请 编辑:程序博客网 时间:2024/03/29 21:04

最近,我自己也是刚刚找到工作,也是面试了很多家公司。也尝试着总结一下,这是我的第一篇面试之后的总结,那么前戏不多,直奔主题,小伙们似乎已经等不及啦。

我们开发的过程中经常的使用代理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也就被释放啦。

原创粉丝点击