2016-04-23 61 views
0

我有一個問題,如果我更改核心數據對象,保存然後刷新對象,導致我的NSFetchedResultsController顯示重複的對象。我想我明白髮生了什麼事情,但我正在尋找某人來確認,並且希望能夠提供更多的細節。NSManagedObjectContext refreshObject導致重複NSFetchedResultsController

爲了更詳細地解釋我有兩個實體FixturePosition。 A Fixture有許多Positions,並且Position只屬於Fixture。要重現此問題,請執行以下操作:

  1. 取所有位置。
  2. 修改該對象Fixture的某個值(任何一個)。 I.E foo.fixture.name = "foobar"
  3. 保存文本
  4. 通過調用context.refreshAllObjectscontext.refreshObject(foo, mergeChanges: false/true)來刷新對象。

我有一個tableview使用顯示Fixures的抓取結果控制器。完成上述操作後,tableview將顯示每個項目的重複項(如果我使用FRC的委託方法執行更新或我只是重新加載tableview,則無關緊要)。

看來發生了什麼是刷新使FRC知道的對象失效,同時獲得另一組對象的知識。如果,如步驟#5,我打電話frc.performFetch(),那麼問題就會消失。

其他注意事項:

  • 無論多少次,我跑我的代碼只有兩每個對象的(我使用隨機按鈕來觸發它用於測試)。
  • 在我的Fixture子類中,只要在下一次代碼運行期間(即調用刷新後)訪問我的對象的Fixture屬性,就會調用init(entityName,context)。
  • 在我的示例一切都承擔同樣的背景下地方(雖然它與兒童環境發生爲好)

給一些更多的背景下,我怎麼擺在首位用戶得到了自己在這種情況下,可以點擊列表中的一個夾具,然後最終縮小到幾個屏幕後的一個位置,在那裏他們可以執行修改夾具的操作。此時應用程序還有其他活動區域正在偵聽NSManagedObjectContextDidSaveNotification,我希望它們更新其對象以便它們可以顯示正確的數據,這就是我調用refresh的原因。

我在文檔中挖了一遍,我看不到任何具體解釋我的理論的東西,即更新上下文會導致NSFetchedResultsController產生無效的對象。任何人都可以闡明這種行爲?

+0

如果您使用的是'NSFetchedResultsController'並且實現了委託方法,那麼控制器將跟蹤所有更改並相應地更新UI。那麼就不需要明確的刷新。 – vadian

+0

顯式刷新發生在完全獨立於NSFetchedResultsController的地方。由於實時服務器更新(在後臺),可能會發生更改。所以在使用FRC的頁面之後的頁面上,我需要獲得最新的信息,這就是爲什麼我要求上下文重新創建對象。 – Brandon

回答

0

首先,你真的不應該凌駕-init...NSManagedObject。這是您強烈不鼓勵覆蓋的方法之一,並且很容易成爲問題的根源。

其次,你的整個UI應使用被關聯到主隊列,因此應該只有在你的UI任何特定實體的ONE實例NSManagedObjectContext的單個實例。如果你有多個上下文,你只是讓自己更復雜。如果您使用單個上下文,請記住,無論您在該上下文中獲取對象的次數多少,都會得到完全相同的指針。

NSFetchedResultsController將永遠不會創建對象,它只會提取並提供它們以供顯示。因此,NSFetchedResultsController僅報告您在代碼中的其他位置創建了此重複的事實。

現在有些問題,是否將這些重複項壓入磁盤?

你可以在磁盤上的存儲文件中看到它們嗎?

當你重新啓動你的應用程序時,重複仍然存在?

當您在NSManagedObject的定製-init方法中放置打印件時;他們會不止一次開火?

+0

爲了說明我沒有實現init,我只使用了一個斷點來跟蹤誰插入了重複。所以發生了什麼是init在我第一次顯式插入對象時調用。然後在刷新後更改屬性時會再次調用它。重複項不會被推到磁盤上,我通過直接查看sqlite文件來驗證重複項,所以當我重新加載應用程序時,重複項不見了。 – Brandon

+0

你確定這些是重複的,而不是顯示錯誤嗎?如果它們沒有被推送到指向表視圖中的顯示錯誤的磁盤而不是創建錯誤。檢查每個對象的'objectID',看它是否完全相同。您的應用中有多少個上下文活動? –

+0

兩個上下文,基本上與您書中的內容相同。對象ID是不同的,並且由FRC返回的「舊」對象具有對臨時id屬性返回true的對象ID。 – Brandon