什么是懶加載
懶加載是延時加載,即在使用到該對象的時候才將其加載到內(nèi)存中沟涨。
為什么要用懶加載
主要目的是為了提升效率
- 在iOS開發(fā)中恤批,加載數(shù)據(jù)的操作一般放在viewDidLoad中,而如果此時展示的界面不需要數(shù)據(jù)裹赴,那我們可能會因為人為的加載了數(shù)據(jù)而影響了系統(tǒng)的性能喜庞。還不如讓系統(tǒng)利用這段時間做它認(rèn)為更加重要的事情。
- 在iOS開發(fā)中棋返,如果某個APP占用內(nèi)存過大延都,系統(tǒng)會給這個APP發(fā)送內(nèi)存警告,一般當(dāng)APP接收到內(nèi)存警告時睛竣,即在
didReceiveMemoryWarning
方法中程序員會做一些清理內(nèi)存的操作晰房,此時我們的數(shù)據(jù)或者其他控件占用的內(nèi)存可能會被清理掉,這時如果再去訪問這塊內(nèi)存就會出現(xiàn)野指針的問題射沟。
綜合以上兩點殊者,我們采用懶加載的方式對數(shù)據(jù)以及控件進行加載,這樣可以保證在使用的時候去加載验夯,而且能保證使用時肯定有猖吴。
怎么用懶加載
懶加載的實現(xiàn),就是重寫對象的getter方法挥转。即在系統(tǒng)調(diào)用某個對象之前先進行判斷,如果有這個對象(即對象不為空)就直接返回這個對象绑谣,如果對象為空就創(chuàng)建它并且返回它。一般而言需要懶加載的是數(shù)據(jù)類型和UI控件借宵,以下將對這兩點分開闡述。
數(shù)據(jù)類型的懶加載
數(shù)據(jù)類型的懶加載一般包括字典暇务,數(shù)組,以及自定義的模型數(shù)據(jù)垦细。以數(shù)組為例,懶加載的實現(xiàn)為:
@interface NewObject()
//聲明一個數(shù)組屬性(數(shù)據(jù)類型聲明為strong)
@property (nonatomic, strong) NSArray * myArray;
@end
@implementation NewObject
//重寫myArray的getter方法
- (NSArray *)myArray{
if (_myArray == nil) {
_myArray = [[NSArray alloc] init];
}
return _myArray;
}
UI控件的懶加載
UI控件一般包括UIView, UIButton等控件括改。以UIButton為例,如果使用storyboard,在連線時系統(tǒng)默認(rèn)在類擴展中自動生成@property (weak, nonatomic) IBOutlet UIButton *myButton;
吝梅。之所以聲明為weak屬性,是因為storyboard已經(jīng)對myButton做了強引用苏携,所以在類擴展中直接聲明為weak屬性,這樣減少了出現(xiàn)內(nèi)存泄露的可能右冻。
而使用純代碼實現(xiàn)時,一般的代碼模式是
@property (weak, nonatomic) UIButton *myButton;
@end
@implementation ViewController
- (UIButton *)myButton{
if (_myButton == nil) {
UIButton * tempButton = [[UIButton alloc] init];
_myButton = tempButton;
[self.view addSubview: _myButton];
}
return _myButton;
}
以上代碼需要注意幾個地方:
為了和storyboard的形式一致纱扭,同時也是為了讓控件在不用的時候能及時被銷毀,屬性也聲明成了weak類型乳蛾。
weak類型的變量就不能使用
_myButton = [[UIButton alloc] init];
進行定義。因為myButton是用weak修飾的肃叶,這樣用[[UIButton alloc] init]
申請的內(nèi)存就只被weak類型的指針指向,而根據(jù)ARC內(nèi)存管理機制被环,如果一個對象不再被strong指針指向详幽,它將會被釋放筛欢。所以此處要利用以上的格式定義這個對象唇聘。即
UIButton * tempButton = [[UIButton alloc] init]; _myButton = tempButton;
這樣在本層大括號的作用域內(nèi)申請的內(nèi)存地址就有強指針指向了。對于子控件必須要加載到父view上才能顯示出來迟郎。所以必須執(zhí)行
addSubview
,而這條語句在懶加載中實現(xiàn)即可。具體原因如以下記錄中的注釋
if (_myButton == nil) {
UIButton * tempButton = [[UIButton alloc] init];
_myButton = tempButton;
[self.view addSubview: _myButton];//調(diào)用addSubview宪肖,self.view 會對myButton有強引用
}//出了這個大括號,tempButton 這個局部對象將會被銷毀控乾,如果前面沒有執(zhí)行addSubview,那新申請的button內(nèi)存又會被釋放
return _myButton;//如果不執(zhí)行addSubview或者其他對button內(nèi)存強引用的語句蜕衡,那么此處返回的將是nil。
當(dāng)然,以上的示例代碼不是絕對的久脯,實現(xiàn)一個功能的方法多種多樣,只不過是自己習(xí)慣了這種寫法帘撰,就簡單記錄一下。
磨礪|分享|提高