将数据从 NSArray 加载到 NSManagedObject
Load data from NSArray to NSManagedObject
是否可以将数据从 .plist 加载到核心数据对象?
我有这个代码:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *name = [plistContent objectForKey:@"Name"];
NSArray *surname = [plistContent objectForKey:@"Surname"];
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
for (NSString *aName in name) {
for (int i = 0; i < name.count; i++) {
[newManagedObject setValue:nameSt forKey:@"name"];
}
}
for (NSString *aSurname in content) {
for (int i = 0; i < content.count; i++) {
[newManagedObject setValue:contentSt forKey:@"surname"];
}
}
[self saveContext];
我有 3 个带名字的字符串和 3 个带姓氏的字符串,但是在
newManagedObject 仅从每个数组加载 1 个字符串。请帮我解决这个问题
您只创建了一个对象,但您应该创建 3 个(在循环内)。您还应该只有 1 个循环(不是您当前拥有的 4 个...):
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *names = [plistContent objectForKey:@"Name"];
NSArray *surnames = [plistContent objectForKey:@"Surname"];
if (names.count == surnames.count) {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
for (int i = 0; i < names.count; i++) {
NSString *name = names[i];
NSString *surname = surnames[i];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newManagedObject setValue:name forKey:@"name"];
[newManagedObject setValue:surname forKey:@"surname"];
}
[self saveContext];
} else {
// error...
}
我认为在 plist 中单独存储姓名和姓氏数组不是一个好习惯...无论如何,如果确实有必要,最好像您的模型一样存储具有结构的人员数组
persons : [
{ name: Angelina,
surname: Jolie
},
{ name: Steven,
surname: Jobs
}
]
那么使用方法setValuesForKeysWithDictionary
就会很容易,没有不必要的循环。如果你有兴趣,我可以展示一个更详细的例子
编辑: 所以如果你的模型中有很多属性,你可以使用 setValuesForKeysWithDictionary
方法一次而不是每个键的 setValue:forKey:
,但是您需要使用这样的映射覆盖模型中的最后一个方法:
+ (NSDictionary *)mappings {
static NSDictionary *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = @{@"Name" : @"name",
@"Surname" : @"surname",
@"some_another_key" : @"your_property_name"};
});
return singleton;
}
- (void)setValue:(id)value forKey:(NSString *)key {
key = [[ModelClass mappings] objectForKey:key] ?: key;
if ([key isEqualToString:@"some_uniq_property"]) {
// ... do anything with value to transform it
// for example to get NSDate from NSString
}
[super setValue:value forKey:key];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
// required method to avoid exception!
// you can intercept some key that you have forgotten to describe in mappings
// you can just retain it empty
NSLog(@"UndefinedKey: %@!!!", key);
}
最后,您的代码将如下所示:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *persons = [plistContent objectForKey:@"Persons"];
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
for (NSDictionary *person in persons) {
ModelClass *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newManagedObject setValuesForKeysWithDictionary:person];
}
[self saveContext];
例如:如果您想要重命名一些键或向您的模型添加新的 属性,您只需要更改映射方法而不是遍历所有项目并搜索每个地方 created\updated您的托管对象
是否可以将数据从 .plist 加载到核心数据对象? 我有这个代码:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *name = [plistContent objectForKey:@"Name"];
NSArray *surname = [plistContent objectForKey:@"Surname"];
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
for (NSString *aName in name) {
for (int i = 0; i < name.count; i++) {
[newManagedObject setValue:nameSt forKey:@"name"];
}
}
for (NSString *aSurname in content) {
for (int i = 0; i < content.count; i++) {
[newManagedObject setValue:contentSt forKey:@"surname"];
}
}
[self saveContext];
我有 3 个带名字的字符串和 3 个带姓氏的字符串,但是在 newManagedObject 仅从每个数组加载 1 个字符串。请帮我解决这个问题
您只创建了一个对象,但您应该创建 3 个(在循环内)。您还应该只有 1 个循环(不是您当前拥有的 4 个...):
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *names = [plistContent objectForKey:@"Name"];
NSArray *surnames = [plistContent objectForKey:@"Surname"];
if (names.count == surnames.count) {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
for (int i = 0; i < names.count; i++) {
NSString *name = names[i];
NSString *surname = surnames[i];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newManagedObject setValue:name forKey:@"name"];
[newManagedObject setValue:surname forKey:@"surname"];
}
[self saveContext];
} else {
// error...
}
我认为在 plist 中单独存储姓名和姓氏数组不是一个好习惯...无论如何,如果确实有必要,最好像您的模型一样存储具有结构的人员数组
persons : [
{ name: Angelina,
surname: Jolie
},
{ name: Steven,
surname: Jobs
}
]
那么使用方法setValuesForKeysWithDictionary
就会很容易,没有不必要的循环。如果你有兴趣,我可以展示一个更详细的例子
编辑: 所以如果你的模型中有很多属性,你可以使用 setValuesForKeysWithDictionary
方法一次而不是每个键的 setValue:forKey:
,但是您需要使用这样的映射覆盖模型中的最后一个方法:
+ (NSDictionary *)mappings {
static NSDictionary *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = @{@"Name" : @"name",
@"Surname" : @"surname",
@"some_another_key" : @"your_property_name"};
});
return singleton;
}
- (void)setValue:(id)value forKey:(NSString *)key {
key = [[ModelClass mappings] objectForKey:key] ?: key;
if ([key isEqualToString:@"some_uniq_property"]) {
// ... do anything with value to transform it
// for example to get NSDate from NSString
}
[super setValue:value forKey:key];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
// required method to avoid exception!
// you can intercept some key that you have forgotten to describe in mappings
// you can just retain it empty
NSLog(@"UndefinedKey: %@!!!", key);
}
最后,您的代码将如下所示:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"List" withExtension:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfURL:url];
NSArray *persons = [plistContent objectForKey:@"Persons"];
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
for (NSDictionary *person in persons) {
ModelClass *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newManagedObject setValuesForKeysWithDictionary:person];
}
[self saveContext];
例如:如果您想要重命名一些键或向您的模型添加新的 属性,您只需要更改映射方法而不是遍历所有项目并搜索每个地方 created\updated您的托管对象