在更新属性后,无法将托管对象保存到核心数据

时间:2010-05-06 14:11:09

标签: iphone objective-c core-data

我没有创建对象的麻烦,但更新失败。 这是创建代码:

 // Save data from pList to core data fro the first time
- (void) saveToCoreData:(NSDictionary *)plistDictionary {

// Create system parameter entity   
SystemParameters *systemParametersEntity = (SystemParameters *)[NSEntityDescription
                                                                insertNewObjectForEntityForName:@"SystemParameters" 
                                                                inManagedObjectContext:mManagedObjectContext];

////
// GPS SIMULATOR
////
NSDictionary *GpsSimulator = [plistDictionary valueForKey:@"GpsSimulator"];

[systemParametersEntity setMGpsSimulatorEnabled:[[GpsSimulator objectForKey:@"Enabled"] boolValue]];
[systemParametersEntity setMGpsSimulatorFileName:[GpsSimulator valueForKey:@"FileName"]];
[systemParametersEntity setMGpsSimulatorPlaybackSpeed:[[GpsSimulator objectForKey:@"PlaybackSpeed"] intValue]];

[self saveAction];  
}

在执行期间,更改缓存的副本,然后将其保存(或尝试)到数据库。以下是保存更改副本的代码:

// Save data from pList to core data fro the first time
- (void) saveSystemParametersToCoreData:(SystemParameters *)theSystemParameters {

// Step 1: Select Data
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"SystemParameters" 
                                          inManagedObjectContext:mManagedObjectContext];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *items = [self.managedObjectContext
                  executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];

if (error) {
    NSLog(@"CoreData: saveSystemParametersToCoreData: Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

// Step 2: Update Object
SystemParameters *systemParameters = [items objectAtIndex:0];

////
// GPS SIMULATOR
////
[systemParameters setMGpsSimulatorEnabled:[theSystemParameters mGpsSimulatorEnabled]];
[systemParameters setMGpsSimulatorFileName:[theSystemParameters mGpsSimulatorFileName]];
[systemParameters setMGpsSimulatorPlaybackSpeed:[theSystemParameters mGpsSimulatorPlaybackSpeed]];



// Step 3: Save Updates
[self saveAction];
}

至于可以看到,我获取了我想要更新的对象,更改其值并保存。 这是保存代码:

- (void)saveAction {

NSError *error;
if (![[self mManagedObjectContext] save:&error]) {
    NSLog(@"ERROR:saveAction. Unresolved Core Data Save error %@, %@", error, [error userInfo]);
    exit(-1);
}
}

持久存储方法:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (mPersistentStoreCoordinator != nil) {
    return mPersistentStoreCoordinator;
}

NSString    *path = [self databasePath];
NSURL *storeUrl = [NSURL fileURLWithPath:path];

NSError *error = nil;
mPersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![mPersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return mPersistentStoreCoordinator;
}

托管对象类定义:

#import <Foundation/Foundation.h>


typedef enum {
UISwitchParameterIdGpsSimulatorEnable,
UISwitchParameterIdIllegal

}UISwitchParameterId;


@interface SystemParameters : NSManagedObject {

//  NSManagedObjectContext  *mManagedObjectContext;

////
// GPS SIMULATOR
////
BOOL mGpsSimulatorEnabled;
NSString *mGpsSimulatorFileName;
NSInteger mGpsSimulatorPlaybackSpeed;


}

@property (nonatomic, assign) BOOL mGpsSimulatorEnabled;
@property (nonatomic, retain) NSString *mGpsSimulatorFileName;
@property (nonatomic, assign) NSInteger mGpsSimulatorPlaybackSpeed;

+ (SystemParameters *)sharedInstance;
- (void) saveToCoreData;


@end

没有错误,但sqLite文件未更新,因此数据不是持久的。

提前致谢。

3 个答案:

答案 0 :(得分:1)

几个月前我遇到了一个非常类似的问题。在模拟器上运行时,我无法更新我的sql存储库。

原来,我正在寻找模拟器的错误应用程序文件夹。如果重新启动模拟器或CPU,它有时会为应用程序创建一个全新的目录。当我写完所有的更改时,我一直在查看原始的应用程序文件夹。

如果那不是问题,我会查看SystemParameters类的定义,看看那里是否有错。错误的自定义访问者或错误的验证代码可能导致对象在不生成错误的情况下不保存数据。

修改

SystemParameters课很奇怪。我认为它不会起作用。

首先,您似乎将其定义为单身人士。核心数据不识别其实体的单例。如果它能够发挥作用,我不确定它会如何发挥作用。

其次,您的标量的属性定义不正确。 Core Data仅存储对象,因此BOOL属性和整数属性必须转换为NSNumber实例。您的属性应如下所示:

@property (nonatomic, retain) NSNumber *mGpsSimulatorEnabled;
@property (nonatomic, retain) NSString *mGpsSimulatorFileName;
@property (nonatomic, retain) NSNumber *mGpsSimulatorPlaybackSpeed;

我建议您让Xcode根据实体图为您生成托管对象子类。这样,您将自动获得正确的类型和正确的处理。

答案 1 :(得分:1)

顺便说一下,这个:

SystemParameters *systemParametersEntity = (SystemParameters *)[NSEntityDescription insertNewObjectForEntityForName:@"SystemParameters" inManagedObjectContext:mManagedObjectContext];

是不必要的演员。 -[NSEntityDescription -insertNewObjectForEntityName: inManagedObjectContext]返回一个通用指针的id。

SystemParameters *systemParametersEntity = [NSEntityDescription insertNewObjectForEntityForName:@"SystemParameters" inManagedObjectContext:mManagedObjectContext];

是对的。 99%的时间,如果你在Objective-C中进行投射,你可能做错了。

答案 2 :(得分:0)

用此代码替换persistentStoreCoordinator方法并尝试

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
}

NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"projectname.sqlite"];
/*
 Set up the store.
 For the sake of illustration, provide a pre-populated default store.
 */
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"projectname" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}

NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.

     Typical reasons for an error here include:
     * The persistent store is not accessible
     * The schema for the persistent store is incompatible with current managed object model
     Check the error message to determine what the actual problem was.
     */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}    

return persistentStoreCoordinator;
}

projectname可以替换为您的项目名称。

我也有同样的问题,我改变了我的persistentStoreCoordinator方法。它工作正常。

一切顺利。