在開(kāi)發(fā)中我們經(jīng)常使用代理,或自己寫個(gè)代理,而代理屬性都用weak(assign)修飾,看過(guò)有些開(kāi)發(fā)者用strong(retain),但并沒(méi)發(fā)現(xiàn)有何不妥,也不清楚weak(assign)與strong(retain)修飾有何區(qū)別
功能實(shí)現(xiàn)就行了,考慮這么多干嘛~~~我只能哈哈哈
-
weak
:指明該對(duì)象并不負(fù)責(zé)保持delegate這個(gè)對(duì)象,delegate這個(gè)對(duì)象的銷毀由外部控制
@property (nonatomic, weak) id<HSDogDelegate>delegate;
-
strong
:該對(duì)象強(qiáng)引用delegate,外界不能銷毀delegate對(duì)象,會(huì)導(dǎo)致循環(huán)引用(Retain Cycles)
@property (nonatomic, strong) id<HSDogDelegate>delegate;
可能你還不太理解,沒(méi)關(guān)系,下面先舉例,看結(jié)果,再分析!
舉例
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>
/** 強(qiáng)引用dog*/
@property (nonatomic, strong) HSDog *dog;
@end
@implementation HSPerson
- (instancetype)init
{
self = [super init];
if (self) {
// 實(shí)例化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實(shí)現(xiàn)
:
#import "ViewController.h"
#import "HSPerson.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 實(shí)例化person, self對(duì)person弱引用,person的retainCount不變
HSPerson *person = [[HSPerson alloc] init];
}
@end
結(jié)果
:
weak修飾代理
@property (nonatomic, weak) id<HSDogDelegate>delegate;
運(yùn)行->打印
:
HSPerson----銷毀
HSDog----銷毀
strong修飾代理
@property (nonatomic, strong) id<HSDogDelegate>delegate;
運(yùn)行->打印
:
....并未打印,說(shuō)明HSPerson、HSDog對(duì)象沒(méi)調(diào)用dealloc方法,兩個(gè)對(duì)象未銷毀
這也是我們經(jīng)常說(shuō)的內(nèi)存泄露,該釋放的內(nèi)存并未釋放!
分析
:
使用strong
person對(duì)dog強(qiáng)引用
@property (nonatomic, strong) HSDog *dog; person
self.dog.delegate又對(duì)person強(qiáng)引用,使person的retainCount + 1
@property (nonatomic, strong) id<HSDogDelegate>delegate;
當(dāng)viewController不對(duì)person引用后,dog.delegate對(duì)person還強(qiáng)引用著,person的retainCount為1,所以person不會(huì)釋放,dog固然也不會(huì)釋放,這就是造成循環(huán)引用的導(dǎo)致內(nèi)存泄露的原因!
- 使用weak
person對(duì)dog強(qiáng)引用
@property (nonatomic, strong) HSDog *dog; person
self.dog.delegate只對(duì)person弱引用,并未使person的retainCount + 1
@property (nonatomic, weak) id<HSDogDelegate>delegate;
所以當(dāng)viewController不對(duì)person引用后,person的retainCount為0,即person會(huì)被釋放,那么dog也被釋放
文章同步到微信公眾號(hào):hans_iOS
有疑問(wèn)可以在公眾號(hào)里直接發(fā)