2016-10-01 67 views
0

我第一次使用Realm作爲coredata的替代品。Realm/iOS:UICollectionView凹凸滾動性能

  1. 不幸的是,當我嘗試Realm時,對於collectionView我有這個顛簸的滾動問題(這不是太差,但很明顯)。沒有數據被下載阻塞主線程,我使用本地存儲的圖像。

  2. 另一個問題是,當我推送到另一個collectionVC時,如果當前的VC將數據傳遞給另一個,那麼segue也很顛簸。

我猜測這是因爲這樣,我寫這篇文章孩子的境界Model屬性。但我不知道什麼可能是計算這個數組值的好方法(將不同類型的列表合併成一個)

非常感謝您提前!

這裏是我使用的的CollectionView的主力機型

class STInstitution: STHierarchy, STContainer { 

    let boxes = List<STBox>() 
    let collections = List<STCollection>() 
    let volumes = List<STVolume>() 

    override dynamic var _type: ReamlEnum { 
     return ReamlEnum(value: ["rawValue": STHierarchyType.institution.rawValue]) 
    } 

    var children: [[AnyObject]] { 

     var result = [[AnyObject]]() 
     var tempArr = [AnyObject]() 

     boxes.forEach{ tempArr.append($0) } 
     result.append(tempArr) 
     tempArr.removeAll() 

     collections.forEach{ tempArr.append($0) } 
     result.append(tempArr) 
     tempArr.removeAll() 

     volumes.forEach{ tempArr.append($0) } 
     result.append(tempArr) 

     return result 
    } 

    var hierarchyProperties: [String] { 
     return ["boxes", "collections", "volumes"] 
    } 
} 

這裏是我如何實現UICollectionViewController:

override func viewDidLoad() { 

    super.viewDidLoad() 

    self.collectionView?.alwaysBounceVertical = true 

    dataSource = STRealmDB.query(fromRealm: realm, ofType: STInstitution.self, query: "ownerId = '\(STUser.currentUserId)'") 

} 

// MARK: - 數據源:

override func numberOfSections(in collectionView: UICollectionView) -> Int { 
    // #warning Incomplete implementation, return the number of sections 
    return 1 
} 


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of items 
    guard let dataSource = dataSource else { return 0 } 
    return dataSource.count 
} 

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! STArchiveCollectionViewCell 

    guard let dataSource = dataSource, 
     dataSource.count > indexPath.row else { 
      return cell 
    } 

    let item = dataSource[indexPath.row] 
    DispatchQueue.main.async { 
     cell.configureUI(withHierarchy: item) 
    } 

    return cell 
} 

// MARK: - 未清項目

func pushToDetailView(dataSource: [[AnyObject]], titles: [String]) { 
    guard let vc = storyboard?.instantiateViewController(withIdentifier: STStoryboardIds.archiveDetailVC.rawValue) as? STArchiveDetailVC 
    else { return } 
    vc.dataSource = dataSource 
    vc.sectionTitles = titles 
    self.navigationController?.pushViewController(vc, animated: true) 
} 

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

    guard let dataSource = self.dataSource, 
     dataSource.count > indexPath.row else { 
      return 
    } 
    let item = dataSource[indexPath.row] 
    self.pushToDetailView(dataSource: item.children, titles: item.hierarchyProperties) 
} 

修改(上configureUI更多代碼):

// configureUI 
// data.type is an enum type 

func configureUI<T: STHierarchy>(withHierarchy data: T) { 
    print("data", kHierarchyCoverImage + "\(data.type)") 
    titleLabel.text = data.title 
    let image = data.type.toUIImage() 
    self.imageView.image = image 
} 

// toUIImage of enum data.type 

func toUIImage() -> UIImage { 

    let key = kHierarchyCoverImage + "\(self.rawValue)" as NSString 

    if let image = STCache.imageCache.object(forKey: key) { 
     return image 
    }else{ 
     print("toUIImage") 
     let defaultImage = UIImage(named: "institution") 
     let image = UIImage(named: "\(self)") ?? defaultImage! 
     STCache.imageCache.setObject(image, forKey: key) 
     return image 
    } 
} 

回答

0

原來我專注於錯誤的一面。我對Realm的缺乏經驗讓我覺得我在Realm做的事情一定會有些問題。然而,真正的罪魁禍首是我忘了定義我的定製單元格的陰影路徑,這反覆繪製是非常昂貴的。直到我使用時間配置文件來檢查哪些方法佔用最多的CPU時,我才發現這一點,我應該首先完成這項工作。

1

如果你的UI是當你顛簸滾動,它只是意味着你在collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell執行操作過於沉重。

領域本身的結構使得從對象中讀取數據的速度非常快,所以如果您所做的只是使用來自Realm的值填充單元格,則您不應該看到大量丟失的幀。

幾個方面的考慮:

  • 如果你調用item.childrencellForItem塊的方法裏面,因爲你手動通過循環和尋呼在每一個領域對象這樣做,這將導致丟幀。如果是的話,最好先提前做,或者重新設計邏輯,以便在絕對需要時訪問這些數組。
  • 你提到你正在包括圖像。即使圖像在磁盤上,除非您提前強制進行圖像解壓縮,Core Animation會在繪製時間延遲地解壓主圖像上的圖像,這可能會嚴重影響滾動性能。有關更多信息,請參閱this question
  • cellForItemAt方法調用應該已經在主線程中,因此在DispatchQueue.main.async閉包中配置您的單元看起來並不是必需的,並且假定它不是同步的,可能由於亂序運行而導致其他問題。
  • 集合視圖以性能而言非常難以執行,因爲在一次運行循環迭代中曾經創建和配置整行單元。這種行爲在iOS 10中進行了更改,以便在多個運行循環迭代中傳播單元格創建。請參閱this WWDC video瞭解如何優化您的收藏視圖代碼以利用此優勢。

如果仍有問題,請張貼更多示例代碼;最重要的是configureUI的內容。謝謝!

+0

謝謝你的所有建議!不幸的是,我在嘗試iOS 10的優化collectionView後仍然遇到這個問題。 1. item.children不在'cellForItem'中調用,只有當用戶點擊單元格觸發一個segue時纔會調用它。 2.我已經註釋了應用圖像的代碼。賽格變成黃油光滑,但是,滾動仍然是顛簸3.請參閱我的問題修改瞭解更多代碼細節。謝謝!!! – Chenglu