Swift 懶加載(lazy)

Swift 懶加載(lazy)

在程序設計中,我們經常會使用 * 懶加載 * ,顧名思義,就是用到的時候再開闢空間,比如iOS開發中的最常用控件UITableView,實現數據源方法的時候,通常我們都會這樣寫

Objective-C

//必須實現的數據源代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1.得到cell
    XWShopCell *cell = [XWShopCell cellWithTableView:tableView];

    //2.傳遞模型
    cell.wine = self.dataArray[indexPath.row];

    //3.回傳cell
    return cell;
}

上面的的代碼中

return self.dataArray.count;

其實就是利用

@property (nonatomic, strong) NSArray *dataArray;

@property 的特性,爲屬性生成了get和set方法,而這裏是調用的get方法,但是上述代碼中 return self.dataArray.count 會調用

- (NSArray *)dataArray
{
    return _dataArray
}

這樣調用,如果成員屬性dataArray 開始沒有賦值的,那麼在使用的時候,調用get方法,不重寫的話,會報錯,空指針,所以一般我們會重寫get方法

//重寫get方法
- (NSArray *)dataArray
{
    if (nil == _dataArray){
        _dataArray = [NSArray array];
    }
    return _dataArray
}

這樣寫,就防止了成員屬性爲沒有賦值的情況

  • 綜上所述,Objective-C的懶加載,其實就是調用成員屬性的get方法,初始化值,而Swift的懶加載,是和Objective-C不同的

Swift

//MARK tablview的 dataSource 代理方法
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return self.dataArray.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
        //1.得到cell
        let cell = XWShopCell.cellWithTableView(tableView)

        //2.傳遞模型
        cell.wine = self.dataArray[indexPath.row]

        //3.回傳cell
        return cell
    }
  • 而這句
        return self.dataArray.count
  • 在Swift 存儲屬性必須初始化,確認類型,或者用可選類型,總之要確認類型,畢竟Swfit是類型安全語言,所以Swift提出了lazy屬性,用法
    //1.分析 NSArray 是一個閉包的返回值,而這是一個沒有參數的閉包
    lazy var dataArray:NSArray = {
        return []
    }()

    //2.也可以寫成這樣
    lazy var dataArray:NSArray = {
        return NSArray()
    }()
    //3.從plist文件加載
   lazy var dataArray:Array<XWWine> = {
            let winePath = NSBundle.mainBundle().pathForResource("wine.plist", ofType: nil)!

            let winesM = NSMutableArray(contentsOfFile: winePath);

            var tmpArray:Array<XWWine>! = []

            for tmpWineDict in winesM! {

                var wine:XWWine = XWWine.wineWithDict(tmpWineDict as!                 NSDictionary)

                  tmpArray.append(wine)
            }

            print("我就運行一次")

            return tmpArray
    }()
  • 上述的代碼,有點難理解,如果之前會Objective-C的block 或者對C語言的函數指針理解透徹的,可以看成是一個代碼塊,然後self.dataArray的時候,就執行了代碼塊,但是重複調用,Lazy 屬性的代碼塊只會調用一次,lazy修飾的是一個存儲屬性,而存放的是閉包,我想內部,應該進行了優化

  • 個人愚見,內部有一個靜態的存儲空間,當空間沒值的時候,就會執行閉包代碼,return 返回值後,就會放到這個存儲空間內,有點像Objective-C的單例對象.

  • 歡迎轉載,但請保留原地址boyXiong
發佈了26 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章