将数据从 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您的托管对象