懶加載:也稱延時加載,即在對象用到的的時候才加載。其實懶加載,就是所謂的重寫對象的get方法,當(dāng)系統(tǒng)或者開發(fā)者調(diào)用對象的get方法時,再去加載對象。
優(yōu)點:
1)不必將創(chuàng)建對象的代碼全部寫在viewDidLoad方法中,代碼的可讀性更強
2)每個控件的getter方法中分別負(fù)責(zé)各自的實例化處理,代碼彼此之間的獨立性強,松耦合
3)對系統(tǒng)的內(nèi)存占用率會減小
示例:
@interface ViewController ()
@property (nonatomic,strong) UIImageView * bgImageView;
@end
@implementation ViewController
//懶加載
-(UIImageView*)bgImageView
{
///判斷是否已經(jīng)有了,若沒有,則進(jìn)行實例化
if (!_bgImageView) {
_bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(40,100,80, 80)];
[self.view addSubview:_bgImageView];
}
return _bgImageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.bgImageView.image =[UIImage imageNamed:@"nilImage"];
}
懶加載寫法:
@interface ViewController ()
@property (nonatomic, weak) UIView *weakView;
@property (nonatomic, strong) UIView *strongView;
@end
@implementation ViewController
/**
UI控件使用弱引用創(chuàng)建方法
1. UIView *weakView = [[UIView alloc] init]; 這句必須聲明一個局部變量, 不能用_weakView,
因為用 _weakView = [[UIView alloc] init], 等號右側(cè)創(chuàng)建了一個View之后,給了一個弱引用持有,相當(dāng)于沒有持有,直接就釋放掉了
而 UIView *weakView = [[UIView alloc] init],等號左側(cè)的weakView默認(rèn)是一個強引用,會暫時持有保住它,但是生命周期就在這個懶加載的大括號內(nèi),所有會有其他代碼配合, 使這個View存活下來, 不被釋放
2. _weakView = weakView; 這句代碼為屬性賦值, 以后在其他位置不管通過self.weakView還是_weakView才能找到這個View,
基本作用可以說等同于強引用的 _strongView = [[UIView alloc] init];
3. [self.view addSubview:weakView], 第一條注釋中說了,UIView *weakView 的生命周期就是在這個{}內(nèi),那么如何保證出了括號依舊存在,就是要給這個View加到一個不會被釋放的View(不一定強引用弱引用)上,即self.view, 這樣就不會被釋放掉了
*/
- (UIView *)weakView {
if (!_weakView) {
UIView *weakView = [[UIView alloc] init];
_weakView = weakView;
weakView.backgroundColor = [UIColor redColor];
[self.view addSubview:weakView];
}
return _weakView;
}
- (UIView *)strongView {
if (!_strongView) {
_strongView = [[UIView alloc] init];
_strongView.backgroundColor = [UIColor greenColor];
}
return _strongView;
}
布局時區(qū)別:
- (void)configView {
WeakSelf(ws);
//弱引用由于懶加載直接加到父視圖上,所以點語法完了直接調(diào)用masonry布局方法即可
[self.weakView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(ws.view);
make.top.equalTo(ws.view).offset(100);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
[self.view addSubview:self.strongView];
[self.strongView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(ws.view);
make.bottom.equalTo(ws.view).offset(-100);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
}
移除之后的區(qū)別(重點,涉及到理解強弱指針):執(zhí)行上述代碼后,屏幕上出現(xiàn)一上一下兩個View, 點擊空白區(qū)域, 移除掉兩個View, 1秒后看一下,1秒后看是因為, 出了這個方法, 也就是運行到結(jié)束的括號之后, 才會把View移除掉, 注意看坐下控制臺兩個View,weakView為nil, 即已被釋放, strongView還是存在, 因為即使從父視圖上移除, self本身對其還有一個強引用, 不會釋放掉,那么如果想把這個View釋放掉需要怎么辦, 就是在[_strongView removeFromSuperview]后面加一句_strongView = nil;
下面圖解一下, 為什么不置空, strongView就不被釋放
總結(jié)起來的話, 其實如果理解到位,使用強弱都沒有問題,但是一般來說,由于弱引用會被及時的釋放掉,所以需求允許的話,一般建議使用弱引用,那什么情況不能使用弱引用呢,這個要看具體需求,舉個例子,如果一個View,需要從父View移除掉,但是之后還有可能加回來,還要保持移除之前的樣子,這種情況強引用會更適合。