![](/img/trans.png)
[英]NSManagedObject Transformable Array of custom objects null/unpopulated
[英]NSManagedObject ignoring changed transformable
對於符合NSCoding的某些對象,我有一個非常基本的緩存系統。 方法獲取對象,提取一些有關鍵和搜索參數的信息,創建或更新NSManagedObject並將其保存到持久性存儲中:
+ (void)updateQuestion:(StacManQuestion *)question site:(StacManSite *)site
{
// 1. Look up with a basic predicate.
SECachedQuestion *cachedQuestion = [SECachedQuestion
findFirstWithQuestionId:question.questionId site:site];
// 2. Create if missing.
if (!cachedQuestion) {
cachedQuestion = [SECachedQuestion MR_createEntity];
cachedQuestion.questionId = question.questionId;
cachedQuestion.site = site.apiSiteParameter;
}
// 3. Update properties.
cachedQuestion.isFavorite = question.favorited;
cachedQuestion.lastAccessTime = [NSDate date];
cachedQuestion.question = question;
// 4. Save
[[NSManagedObjectContext MR_contextForCurrentThread]
MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
/* ... */
}];
}
第一次運行此代碼,它可以完美運行。 該對象將保存到緩存中,並立即可用於下一次運行。 但是,此后,將新值分配給cachedQuestion.question
不執行任何操作。
我添加了一些斷點,並發現以下內容:
問題的分配不會更新changedValues
:
(lldb) po [cachedQuestion changedValues] { lastAccessTime = "2014-07-16 17:16:45 +0000"; }
question
和cachedQuestion.question
從不同的地址開始,然后以相同的地址結束,因此肯定發生了分配。
如果我在設置cachedQuestion.question = nil
的賦值之前放了一步, cachedQuestion.question = nil
得到以下信息,但問題記錄將在重新賦值時再次消失。
(lldb) po [cachedQuestion changedValues] { lastAccessTime = "2014-07-16 17:16:45 +0000"; question = "<null>"; }
這是另一件事。 我繼續進行了測試,在其中我為一些應用程序版本設置了 cachedQuestion.question = nil
。這對於單次運行中的后續查找而言效果很好,但是每次應用程序啟動對cachedQuestion.question的第一次讀取時,question都會返回原始值! 我可以確認開始創建新的緩存問題, 並且 lastAccessTime更新沒有問題。 正是這一領域被及時凍結了。 這是因為數據驗證。 nil
使它顯示為更改后的值,但保存失敗,因為它不是可選的。
UPDATE
現在,我正在做一個令人傷心的事,任何時候只要有更改,我都會刪除舊記錄並插入新記錄。 它運作良好,但我更想知道出了什么問題。
您沒有將更改寫到正確的上下文中。 首先,停止使用contextForCurrentThread。 不推薦使用它,它會導致您崩潰100次中有1次,這太多了。 您還可能會崩潰,因為此方法可以並且將返回不是默認上下文的上下文。 出於充分的原因,跨上下文進行管理對象分配也會崩潰。
相反,您應該顯式創建您的上下文,對它進行更改,然后在方法末尾保存它。 那可能會解決您所看到的大多數問題。
我不得不讀過幾次……我認為這里的問題是您沒有正確使用關系。 NSManagedObjects應該設置為實體。
它不應該是可變形的,而是與實體的關系。
從上下文中,您可以首先獲取MutableArray中第一個實體中的所有對象,然后通過選擇一個對象時調用該對象的關系,通過關系來獲取新的MutableArray對象中的所有相關對象:
self.newArray = [[self.oldObject.relationshipName allObjects] mutableCopy];
然后,您將僅獲取與所選對象相關的內容,而不會獲取相關實體中的所有對象。
這意味着不應有問題屬性,而應與實體問題有關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.