【问题标题】:Load data from NSArray to NSManagedObject将数据从 NSArray 加载到 NSManagedObject
【发布时间】:2015-03-07 11:18:24
【问题描述】:

是否可以将数据从 .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 个字符串。请帮我解决这个问题

【问题讨论】:

    标签: ios objective-c arrays core-data


    【解决方案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...
    }
    

    【讨论】:

      【解决方案2】:

      我认为将姓名和姓氏数组单独存储在 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];
      

      例如:如果您想要重命名某个键或向模型添加新属性,您只需要更改映射方法,而不是遍历所有项目并搜索创建\更新您的托管对象的每个地方

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多