2017-04-17 107 views
0

我遇到了這個巨大的性能問題,而在它的核心數據的圖像保存NSAttrbutedString。在NSAttributedString添加圖像,並保存到核心數據peformance

CoreData Schema

有一個UITextView其中允許用戶輸入文本以及添加圖像。當用戶輸入完成並點擊'完成'按鈕時,它將被保存到CoreData,並顯示在一個TableView中。

這裏是我保存的內容時,點擊「完成」按鈕:

創建私人MOC和分配AppDelegates managedObjectContext作爲其父MOC。

privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) 
privateMOC.parent = managedObjectContext 

privateMOC.perform { 
    do { 
     try self.privateMOC.save() 

     self.managedObjectContext.performAndWait { 
     do { 
      try self.managedObjectContext.save() 
     } catch { 
      fatalError("Failure to save context: \(error)") 
     } 
     } 
    } catch { 
     print("Could not save \(error)") 
    } 
    } 

這裏有兩個問題:

  1. 取決於圖像,當我點擊「完成」按鈕,用戶界面被阻塞,需要3 - 駁回視圖前5秒,在所示TableView中。

  2. 我檢查實際的數據庫.sqlite發現,一個單一的新增條目(文本和圖像的UITextView)會使數據庫大小增加幾乎12MB! (也許圖像需要太多的空間?)

任何建議如何解決這些問題? 謝謝!

回答

0

這些問題都將是困難的,以防止你的使用情況。通過在NSAttributedString包含圖像的使用NSCoding,什麼你問的是一個二進制的blob,你不能以任何方式控制編碼過程。

  • 這可能是圖像大小膨脹,例如,因爲你保存的是未壓縮的數據而不是PNG或JPEG。但你無法做任何事情,因爲你無法控制NSAttributedString如何處理它。所以你可能會遇到大數據量的問題。
  • 長的處理時間可能連接到前point--你不能控制NSAttributedString在內部做,但很可能是大量的那段時間吸收處理圖像(S)。

如果您自己對屬性字符串進行編碼而不是使用可變形屬性,則可能會縮短保存時間。然後,您可以在後臺啓動編碼,而不是在保存數據時進行編碼。您可能無法修復編碼時間,但您可能能夠儘早實現並且不太明顯。不過,只要您使用編碼的歸屬字符串,我認爲您的尺寸就會受到限制。

我不知道你的程序是做什麼,但如果你可以從潛在的巨大NSAttributedString小號脫身,你會避免您遇到的問題。

+0

非常感謝您的詳細解釋!你是對的!圖像的大小是巨大的(〜13MB),沒有任何壓縮。我試圖保存原始圖像。 原點圖象寬度:2448.0 原點圖像高度:3264。0 原點圖像大小(字節):13532006(〜** 13MB **!) 壓縮後圖像寬度:可選(750.0) 壓縮後圖像高度:可選(1000.0) 壓縮後圖像大小(字節):908975(** 〜900kb **) 壓縮後,速度更快。但是,它在保存上下文的同時仍會阻止用戶界面。我如何將它保存在背景中而不會阻擋我的用戶界面? – artekr

+0

我在考慮用二進制Core Data屬性而不是可變形的,你必須自己調用'NSCoding'方法。在嘗試保存更改之前,您可以在後臺隊列中執行此操作。你可能使用'NSKeyedArchiver'來編碼和'NSKeyedUnarchiver'來解碼。 –

+0

謝謝!問題是內容設置爲可變形,而我沒有選擇將其更改爲二進制。因爲否則我必須進行數據庫遷移,將之前的所有內容轉換爲二進制文件(之前我做過遷移,這非常痛苦,許多用戶甚至丟失了他們的數據:()。 – artekr