iOS中使用UI控件時(shí),修飾符用strong?還是weak好呢?
大部分iOS工程師一般寫代碼的時(shí)候,都會(huì)使用strong,這是為了方便、快捷、不易報(bào)錯(cuò),有的時(shí)候如果寫成weak,會(huì)莫名其妙的報(bào)錯(cuò),比如崩潰,但是看代碼卻沒有問題。當(dāng)然細(xì)心的工程師其實(shí)在使用Xcode的時(shí)候,在一個(gè)地方會(huì)發(fā)現(xiàn),系統(tǒng)所使用的UI控件修飾符全是weak,當(dāng)你用xib、view等拖控件關(guān)聯(lián)時(shí),這個(gè)時(shí)候系統(tǒng)提供的修飾符全部是weak,所以,其實(shí)官方推薦在實(shí)際開發(fā)中盡量用weak,那么怎么驗(yàn)證呢,我們可以通過一個(gè)示例程序來進(jìn)行說明。
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIView *strongView;
@property (nonatomic,strong) UIView *selfStrongView;
@property (nonatomic,weak) UIView *weakView;
@property (nonatomic,weak) UIView *selfWeakView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1、創(chuàng)建selfStrongView
self.selfStrongView = [[UIView alloc]initWithFrame:CGRectMake(50, 25, 50, 50)];
printf("self.selfStrongViewretain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfStrongView)));
[self.view addSubview:self.selfStrongView];
printf("self.selfStrongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfStrongView)));
_strongView = [[UIView alloc]initWithFrame:CGRectMake(150, 100, 50, 50)];
printf("_strongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
[self.view addSubview:self.strongView];
printf("_strongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
UIView *selfView = [[UIView alloc]initWithFrame:CGRectMake(250, 150, 50, 50)];
self.selfWeakView = selfView;
printf("self.selfWeakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfWeakView)));
[self.view addSubview:self.selfWeakView];
printf("self.selfWeakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfWeakView)));
UIView *weaksView = [[UIView alloc]initWithFrame:CGRectMake(300, 200, 50, 50)];
printf("weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(weaksView)));
_weakView = weaksView;
printf("_weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
[self.view addSubview:_weakView];
printf("_weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
}
- (void)viewWillAppear:(BOOL)animated
{
printf("self.selfStrongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
printf("_strongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
printf("self.selfWeakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfWeakView)));
printf("_weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
}
@end
總結(jié)
在現(xiàn)在開發(fā)中,一般都是在ARC中,對于ARC來說,對象釋放的最終根據(jù)還是根據(jù)引用計(jì)數(shù)為0時(shí)去釋放。而weak與strong的根本區(qū)別是在set方法中,weak的set方法和strong的set方法都是釋放舊值保留新值,但是weak的set方法會(huì)對其autorelease,即延遲release一次,而strong的set方法也是釋放舊值保留新值,但是其不會(huì)延遲release。最終效果是strong會(huì)+1,weak不會(huì)+1.
要注意,用去賦值的時(shí)候是不調(diào)用set方法的,也就是說無論weak還是strong,只要用賦值都不會(huì)對引用計(jì)數(shù)加1,區(qū)別在于self.語法會(huì)調(diào)用set方法,strong的self.會(huì)調(diào)用set方法+1.而weak的_和self.語法都不會(huì)+1.
所以,建議用weak,用weak時(shí)無論用_和.語法都不會(huì)導(dǎo)致+1。用strong時(shí)用self.語法會(huì)導(dǎo)致+1.建議用weak。同時(shí)weak在對象回收以后可以將對象指針置成nil。