[英]Core Data saving problem: can't update transformable attribute (NSArray)
[英]Core Data not saving transformable NSMutableDictionary
我有兩個類:Profile和Config。 配置文件包含NSSet的Config對象。 Profile和Config都是NSManagedObject
子類。
@interface Profile : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *configs;
- (void)print;
@end
這是Config類
@interface Config : NSManagedObject
@property (nonatomic, retain) NSString * otherdata;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSMutableDictionary *myDict;
@property (nonatomic, retain) Profile *profile;
- (void)print;
@end
字典myDict具有NSString
*鍵和值。 現在,當我對myDict進行任何更改時,我調用NSManagedObject
保存方法,並且沒有錯誤,工作正常。 只要我不殺死應用程序,一切都按預期運行。
但是當我強制殺死應用程序時(無論是在Xcode中還是通過雙擊主頁按鈕並在底部的按鈕行中將其刪除)然后重新啟動應用程序,myDict中的數據將恢復為之前的狀態,即新的數據實際上沒有保存。 它似乎只是在我殺死應用程序之前保存。
myDict在xcdatamodeld文件中列為Transformable。 我試了一下,沒有指定任何NSTransformer
類。 我也嘗試過指定一個變換器類MyDictTransformer,在Config中我添加了這段代碼:
在Config.h中:
@interface MyDictTransformer : NSValueTransformer
@end
在Config.m中:
@implementation MyDictTransformer
+ (Class)transformedValueClass
{
return [NSMutableDictionary class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
return [NSKeyedArchiver archivedDataWithRootObject:value];
}
- (id)reverseTransformedValue:(id)value
{
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
}
@end
另外在Config.m的頂部我有這個:
//
// from: http://stackoverflow.com/questions/4089352/core-data-not-updating-a-transformable-attribute
//
+ (void)initialize {
if (self == [Config class]) {
MyDictTransformer *transformer = [[MyDictTransformer alloc] init];
[NSValueTransformer setValueTransformer:transformer forName:@"MyDictTransformer"];
}
}
同樣在AppDelegate中,在applicationDidEnterBackground
和applicationWillTerminate
我調用saveContext:
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
無論我嘗試過什么,它都不會在Config中保存字典。 它保存config.name之類的任何其他更改,但不保存在config.myDict中。
A)我做錯了什么? B)我怎樣才能解決這個問題,即使我必須使用一些其他數據結構而不是NSMutableDictionary
來保存數據?
你已經將myDict
聲明為NSMutableDictionary
,這是一個很大的紅旗。
托管對象屬性永遠不應該是可變類型
有可能,你正在使用myDict
這樣的東西:
someConfig.myDict[@"someKey"] = @"someValue";
[context save:&error];
問題是,你沒有調用someConfig
的setter方法,所以你沒有做任何事情來通知它屬性已被更改。 即使你正在調用save:
:,上下文也不會為保存未更改的對象而煩惱。
嚴格來說,每次更改myDict
時,你都可以通過調用[someConfig didChangeValueForKey:@"myDict"]
myDict
。 我不推薦它,因為它很容易忘記並且容易出錯。
最好將myDict
聲明為不可變並使用它如下:
@property (nonatomic, retain) NSDictionary *myDict;
...
NSMutableDictionary *updatedDict = [someConfig.myDict mutableCopy];
updatedDict[@"someKey"] = @"someValue";
someConfig.myDict = [updatedDict copy];
[context save:&error];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.