我对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。
非常感谢你的帮助。
答案 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];
...始终定义newManagedObject
类NSManagedObject
。
常常混淆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"];
}