如何在一个方法中的两个不同实体中插入数据?

时间:2011-02-26 12:24:12

标签: iphone core-data

我对coredata很新。我的目标是在一个函数内将数据写入不同的实体。我已经在我的应用程序委托中初始化了coredata并将其传递给我的viewcontroller。在我的viewController中,我想决定情境依赖,应该使用哪个实体。所以我编辑了fetchedResultsController方法的代码,如下所示:

-(NSFetchedResultsController *)fetchedResultsControllerForEntityWithString:(NSString*)theEntityString {
...
NSEntityDescription *entity = [NSEntityDescription entityForName:theEntityString inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
...
}

我改变的第二种方法是saveContext:

-(void)saveContextForEntityWithString:(NSString*)theEntityString {
    NSManagedObjectContext *contex = [self fetchedResultsControllerForEntityWithString:theEntityString managedObjectContext];
...
}

为了插入新数据,我写了一个新方法:

-(void)insertEntityForString:(NSString*)theEntityName {
NSManagedObjectContext *context = [[self fetchedResultsControllerForEntityWithString:theEntityName] managedObjectContext];
NSEntityDescription *entity = [[[self fetchedResultsControllerForEntityWithString:theEntityName] fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

if ([newManagedObject isKindOfClass:[myClass1 class]]) {
    newManagedObject.testValue:[NSDate date];
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) {

}

}

不幸的是,这种方法不会成功。 Xcode不知道testValue是否存在并且引发错误。

希望你能帮助我更好地理解如何正确设置coredata。

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:0)

newManagedObject.testValue:[NSDate date];

是修改问题代码时发生的:错字吗?

并且您始终可以使用setValue:forKey:来设置核心数据对象的属性。 喜欢

[newManagedObject setValue:[NSDate date] forKey:@"testValue];

另一个选项是一个抽象实体及其在两个实体的类中用作超类的对象

答案 1 :(得分:0)

这个测试:

if ([newManagedObject isKindOfClass:[myClass1 class]]) {

...总是会失败,因为这一行:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

...始终定义newManagedObjectNSManagedObject

常常混淆entites,NSManagedObject类和NSManagedObject子类。

实体是类似于类定义的抽象。它们告诉托管对象上下文如何构造对象中的数据。

NSManagedObject令人困惑,因为NSManagedObject的任何通用实例都可以使用关联存储来存储来自任何实体的数据。关联存储就像字典一样工作。实体提供字典的键。所以,像这样的一行:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

...将通用NSManagedObject实例插入上下文,然后将其关联存储的键名设置为实体定义的名称。无论实体提供其密钥,对象的类始终是NSManagedObject。

在创建锁定到特定实体的NSManagedObject的子类时,只会看到另一个类。实体的关键名称成为类的已定义属性。

通过移动fetchedResultControllers,我不知道你在设计中究竟拍摄了什么。通常,这会产生一个非常混乱的界面,因为用户希望单个表呈现相同的数据。通常,您将使用不同的表来显示来自不同实体的数据,以便用户可以根据数据的变化来定位自己。

但是,如果您仍想要这样做,最简单的方法是为您的tableview控制器定义currentEntity属性。像这样:

@property(nonatomic, retain)  NSString *currentEntity;

...然后在fetchedResultsController getter方法中添加一个测试:

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        if ([[[fetchedResultsController entity] name] isEqualToString:self.currentEntity]) {
            return fetchedResultsController;
        }
    }
    // configure the FRC as normal but for the fetch entity name use currentEntity
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.currentEntity inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    //....

现在,要更改控制器提取的实体,只需更改currentEntity中存储的名称即可。下次调用FRC时,它将自动重置为新的实体提取。

但是,我必须警告你FRC和相关的表方法并没有真正设置为这样交换。您将不得不小心表更新,我认为它不可靠或稳定。

答案 2 :(得分:0)

如果您已将myClass1和myClass2定义为子类,则可以执行以下操作:

-(void)insertEntityForString:(NSString*)theEntityName {
NSManagedObjectContext *context = [[self fetchedResultsControllerForEntityWithString:theEntityName] managedObjectContext];
NSEntityDescription *entity = [[[self fetchedResultsControllerForEntityWithString:theEntityName] fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

if ([newManagedObject isKindOfClass:[myClass1 class]]) {
    myClass1 *newMyClass1 = (myClass1)newManagedObject;
    newMyClass1.testValue = [NSDate date];
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) {
    myClass2 *newMyClass2 = (myClass2)newManagedObject;
    newMyClass2.someOtherValue = @"Hi, Hello";
}

如果没有,你的if语句将如下所示:

if ([newManagedObject isKindOfClass:[myClass1 class]]) {
    [newManagedObject setValue:[NSDate date] forKey:@"testValue"];
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) {
    [newManagedObject setValue:@"Hi, Hello" forKey:@"someOtherName"];
}