核心数据一对一关系 returns NULL

Core Data to-one relationship returns NULL

Batting.team 关系并不总是正确保存并且 returns 有时为 null

大约 100 个 'Team' NSManagedObjects 被保存并且可以按预期记录它们的属性。然后大约 15000 'Batting' NSManagedObjects 被保存并且所有属性都正确记录除了关系。

我希望 Batting.team 关系指向与 Batting.teamID 具有相同 Team.teamID 值的团队对象。

当设置 Batting 关系时,我创建了一个谓词来搜索特定的 Team.teamID,获取请求并假设将该 Team 对象设置为等于我的 Batting.team 关系。有时会设置关系属性,但大多数时候不会设置,我无法弄清楚

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    NSError *error;

    NSString* dataPath_TEAMS = [[NSBundle mainBundle] pathForResource:@"teams" ofType:@"json"];
    NSArray* TEAMS = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath_TEAMS] options:kNilOptions error:&error];   

    NSString* dataPath_ABC = [[NSBundle mainBundle] pathForResource:@"abc" ofType:@"json"];
    NSArray* BATTING_ABC = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath_ABC] options:kNilOptions error:&error];



    //insert Team objects
    NSFetchRequest *fetchRequestTeams = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityTeams = [NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    [fetchRequestTeams setEntity:entityTeams];

    for (id t in TEAMS) {
        Team *team = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];

        team.name       = [t objectForKey:@"name"];
        team.minYearID  = [t objectForKey:@"minYearID"];
        team.maxYearID  = [t objectForKey:@"maxYearID"];
        team.teamID     = [t objectForKey:@"teamID"];

        if (![self.managedObjectContext save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }
    NSArray *fetchedObjectsTeams = [self.managedObjectContext executeFetchRequest:fetchRequestTeams error:&error];
    NSLog(@"Number of records in teams.json - %d", (int)[fetchedObjectsTeams count]);


    //insert Batting objects
    NSFetchRequest *fetchRequestBatting = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityBatting = [NSEntityDescription entityForName:@"Batting" inManagedObjectContext:self.managedObjectContext];
    [fetchRequestBatting setEntity:entityBatting];

    for (id b in BATTING_ABC) {
        Batting *batting = [NSEntityDescription insertNewObjectForEntityForName:@"Batting" inManagedObjectContext:self.managedObjectContext];

        batting.playerID    = [b objectForKey:@"playerID"];
        batting.h           = [b objectForKey:@"h"];
        batting.ab          = [b objectForKey:@"ab"];
        batting.hr          = [b objectForKey:@"hr"];
        batting.rbi         = [b objectForKey:@"rbi"];
        batting.sb          = [b objectForKey:@"sb"];
        batting.r           = [b objectForKey:@"r"];
        batting.bb          = [b objectForKey:@"bb"];
        batting.so          = [b objectForKey:@"so"];
        batting.yearID      = [b objectForKey:@"yearID"];
        batting.teamID      = [b objectForKey:@"teamID"];

        NSPredicate *teamIDPredicate = [NSPredicate predicateWithFormat:@"teamID == %@", [b objectForKey:@"teamID"]];
        [fetchRequestTeams setPredicate:teamIDPredicate];
        NSArray *fetchedSpecificTeam = [self.managedObjectContext executeFetchRequest:fetchRequestTeams error:&error];

        batting.team = [fetchedSpecificTeam firstObject];

        if (![self.managedObjectContext save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }

    fetchedObjectsBatting = [self.managedObjectContext executeFetchRequest:fetchRequestBatting error:&error];
    for (Batting *b in fetchedObjectsBatting) {
        NSLog(@"playerID:   %@", b.playerID);
        NSLog(@"yearID:     %@", b.yearID);
        NSLog(@"teamID:     %@", b.teamID);
        NSLog(@"team:       %@\n\n", b.team.name);
    }

    return YES;
}

从您模型的屏幕截图来看,它被配置为每个 Team 只能有一个 Batting。每次将 batting.team 设置为给定的 Team 时,CoreData 会将 link 从 Team 移除到其当前的 Batting 对象(从而设置 Batting 对象的 team 为零)。

您应该使用数据模型检查器将 Team 实体的 batting 关系定义为 "to-Many"(每个 Team 可以有多个 Battings)在模型编辑器中的右侧: