【发布时间】:2014-06-24 18:15:48
【问题描述】:
我有一项服务可以获取使用以下 json 响应的员工:
[{ "initials": "PR", "name": "Paul", "accounts": ["SPA", "ITA"] },
{ "initials": "SR", "name": "William", "accounts": ["ITA"] } ]
和另一个服务来获取导致这样的 json 的帐户:
[{ "code": "SPA", "name": "Spain", "employees": ["PR"] },
{ "code": "ITA", "name": "Italy", "employees": ["PR", "SR"] } ]
我需要解析接收到的信息并将其插入到核心数据数据库中,该数据库具有两个核心数据模型,员工和帐户,声明了多对多的关系。它们声明如下:
@interface Employee : NSManagedObject
@property (nonatomic, retain) NSString *initials;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *accounts;
@end
@interface Account : NSManagedObject
@property (nonatomic, retain) NSString *code;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *employees;
@end
我现在做的是先插入员工,然后创建每个帐户并查询要插入每个帐户的员工。显然,这样做的性能非常糟糕,因为我需要为每个帐户做一个请求。
- (void)loadEmployeesJSON { ... }
- (void)loadAccountsJSON {
NSManagedObjectContext *context = self.managedObjectContext;
NSError *err = nil;
NSString *dataPath = [[NSBundle mainBundle] pathForResource:@"Accounts" ofType:@"json"];
NSArray *accounts = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath] options:kNilOptions error:&err];
[accounts enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
Account *account = [NSEntityDescription insertNewObjectForEntityForName:@"Account" inManagedObjectContext:context];
account.code = [obj objectForKey:@"code"];
account.name = [obj objectForKey:@"name"];
account.employees = [self accountsForEmployee:[obj objectForKey:@"employees"]];
NSError *error;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}];
}
- (NSSet*)accountsForEmployee:(NSArray*)initialsArray {
NSManagedObjectContext *context = self.managedObjectContext;
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:context];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"initials IN %@", initialsArray]];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
return [NSSet setWithArray:fetchedObjects];
}
如何在不要求每个帐户的员工的情况下链接它们? 我认为我可以在内存中映射所有员工并要求他们。但是,如果我的员工数据库太大(+100.000)而无法存储在内存中怎么办?
【问题讨论】:
-
对您来说更好的方法可能是不使用多对多关系,而是只使用您在引用时懒惰地创建的只读帐户(和员工)属性。
-
我不会推荐这种方法。它破坏了使用 Core Data 的意义。
标签: ios json xcode performance core-data