簡體   English   中英

Core Data不保存可轉換的NSMutableDictionary

[英]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中,在applicationDidEnterBackgroundapplicationWillTerminate我調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM