在開(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) iddelegate;
strong:該對(duì)象強(qiáng)引用delegate瘟芝,外界不能銷毀delegate對(duì)象,會(huì)導(dǎo)致循環(huán)引用(Retain Cycles)
@property (nonatomic, strong) iddelegate;
可能你還不太理解褥琐,沒(méi)關(guān)系锌俱,下面先舉例,看結(jié)果敌呈,再分析贸宏!
舉例
HSDog類
HSDog.h:
@protocol HSDogDelegate
@end
@interface HSDog : NSObject
@property (nonatomic, weak) iddelegate;
@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()
/** 強(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) iddelegate;
運(yùn)行->打游鱿浴:
HSPerson----銷毀
HSDog----銷毀
strong修飾代理
@property (nonatomic, strong) iddelegate;
運(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) iddelegate;
當(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) iddelegate;
所以當(dāng)viewController不對(duì)person引用后,person的retainCount為0陨簇,即person會(huì)被釋放吐绵,那么dog也被釋放