0

在将数据添加到具有一对多关系的核心数据模型中时遇到了一些麻烦。

下面是我的模型:

RecordDate - Relationship: records - One to Many with RecordWorkout.
RecordWorkout - Relationship: recExercises - One to Many With RecordExercise.
RecordExercise - Relationship: sets - One to Many With RecordSet.
RecordSet

RecordDate 保存单个字符串变量日期。(不存储重复的日期变量)

RecordWorkout 包含一个字符串变量 recWorkoutName。(不能存储 recWorkoutName 的重复变量。)

RecordExercise 保存一个字符串变量recExerciseName。(也不能存储 recExerciseName 的重复变量。

RecordSet 包含三个字符串变量(setLog、weight、reps)。(同样不能为 setLog 变量存储重复的变量。

代码目标:

目标是单击按钮(日志按钮)时,单击按钮时,代码需要将屏幕上的值与数据存储中已有的值进行比较,因此不会存储重复的值。

例子:

日期 > 锻炼名称 > 锻炼 > (许多组,例如:set1、set2、set3、set4)

在第一次单击按钮日期时,会存储锻炼名称、锻炼名称和第一组详细信息。在第二次单击时,仅存储新的设置数据。

下面是我正在使用的代码,但它似乎没有存储所有的设置值,一些集合从数据存储中丢失,或者只存储了第一个集合。

setCount = setCount + 1;
NSString *weight = weightTextField.text;
NSString *reps = repsTextField.text;


NSString *setStr = [NSString stringWithFormat:@"%d", (int)setCount];

NSMutableString *log = [NSMutableString stringWithFormat:@"%@ %@%@ %@ %@ %@ %@", @"Set", setStr, @":", weight, @"kg X", reps, @"reps"];
[self.tempLog addObject:log];
[self.myTableView reloadData];
[weightTextField resignFirstResponder];
[repsTextField resignFirstResponder];
//the set is stored in a temporary mutable array (tempLog) just to show in tableview
//i would rather just store it in the actual entity and fetch from there

//Entities are initialised below
NSEntityDescription *recordDateEntity = [NSEntityDescription entityForName:@"RecordDate"
                                                    inManagedObjectContext:self.managedObjectContext];

NSEntityDescription *recordWorkoutEntity = [NSEntityDescription entityForName:@"RecordWorkout"
                                                       inManagedObjectContext:self.managedObjectContext];

NSEntityDescription *recordExerciseEntity = [NSEntityDescription entityForName:@"RecordExercise"
                                                        inManagedObjectContext:self.managedObjectContext];

NSEntityDescription *recordSetEntity = [NSEntityDescription entityForName:@"RecordSet"  inManagedObjectContext:self.managedObjectContext];

//Data is fetched from the existing store to be compared with the data on screen
//This data is stored in mutable arrays (record date, recordworkouts, recordexercises, recordsets)
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"RecordDate"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date == %@", dateLabel.text];
[fetchRequest setPredicate:predicate];
self.recorddates = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

NSFetchRequest *fetchRWRequest = [[NSFetchRequest alloc] initWithEntityName:@"RecordWorkout"];
NSPredicate *predicateRW = [NSPredicate predicateWithFormat:@"recWorkoutName == %@", testLabel2.text];
[fetchRWRequest setPredicate:predicateRW];
self.recordworkouts = [[managedObjectContext executeFetchRequest:fetchRWRequest error:nil] mutableCopy];

NSFetchRequest *fetchRERequest = [[NSFetchRequest alloc] initWithEntityName:@"RecordExercise"];
NSPredicate *predicateRE = [NSPredicate predicateWithFormat:@"recExerciseName == %@", exNameLabel.text];
[fetchRERequest setPredicate:predicateRE];
self.recordexercises = [[managedObjectContext executeFetchRequest:fetchRERequest error:nil] mutableCopy];

NSFetchRequest *fetchRSetRequest = [[NSFetchRequest alloc] initWithEntityName:@"RecordSet"];
NSPredicate *predicateRSet = [NSPredicate predicateWithFormat:@"setLog == %@", setStr];
[fetchRSetRequest setPredicate:predicateRSet];
self.recordsets = [[managedObjectContext executeFetchRequest:fetchRSetRequest error:nil] mutableCopy];

if ([self.recorddates count] == 0) {

    NSLog(@"No Dates Imported");

    RecordDate *newRecordDate = (RecordDate *)[[NSManagedObject alloc]
                                               initWithEntity:recordDateEntity
                                               insertIntoManagedObjectContext:self.managedObjectContext];
    newRecordDate.date = dateLabel.text;

    RecordWorkout *newRecordWorkout = (RecordWorkout *)[[NSManagedObject alloc]
                                                        initWithEntity:recordWorkoutEntity
                                                        insertIntoManagedObjectContext:self.managedObjectContext];

    newRecordWorkout.recWorkoutName = testLabel2.text;
    [newRecordDate addRecordsObject:newRecordWorkout];

    RecordExercise *newRecordExercise = (RecordExercise *)[[NSManagedObject alloc] initWithEntity:recordExerciseEntity insertIntoManagedObjectContext:self.managedObjectContext];

    newRecordExercise.recExerciseName = exNameLabel.text;
    [newRecordWorkout addRecExercisesObject:newRecordExercise];



    RecordSet *newRecordSet = (RecordSet *)[[NSManagedObject alloc]
                                            initWithEntity:recordSetEntity
                                            insertIntoManagedObjectContext:self.managedObjectContext];

    newRecordSet.setLog = setStr;
    newRecordSet.weight = weight;
    newRecordSet.reps = reps;
    [newRecordExercise addSetsObject:newRecordSet];

    NSLog(@"Set number one should be added to model: %@", setStr);

} else {

    NSLog(@"Dates Are Imported");

    RecordDate *prevRecordDate = (RecordDate *)[self.recorddates objectAtIndex:0];

    if ([self.recordworkouts count] == 0) {

        RecordWorkout *newRecordWorkout = (RecordWorkout *)[[NSManagedObject alloc]
                                                            initWithEntity:recordWorkoutEntity
                                                            insertIntoManagedObjectContext:self.managedObjectContext];
        newRecordWorkout.recWorkoutName = testLabel2.text;
        [prevRecordDate addRecordsObject:newRecordWorkout];

        RecordExercise *newRecordExercise = (RecordExercise *)[[NSManagedObject alloc] initWithEntity:recordExerciseEntity insertIntoManagedObjectContext:self.managedObjectContext];

        newRecordExercise.recExerciseName = exNameLabel.text;
        [newRecordWorkout addRecExercisesObject:newRecordExercise];

        RecordSet *newRecordSet = (RecordSet *)[[NSManagedObject alloc]
                                                initWithEntity:recordSetEntity
                                                insertIntoManagedObjectContext:self.managedObjectContext];

        newRecordSet.setLog = setStr;
        newRecordSet.weight = weight;
        newRecordSet.reps = reps;
        [newRecordExercise addSetsObject:newRecordSet];

    } else {

        RecordWorkout *prevRecordWorkout = [self.recordworkouts objectAtIndex:0];


        if ([self.recordexercises count] == 0) {

            RecordExercise *newRecordExercise = (RecordExercise *)[[NSManagedObject alloc] initWithEntity:recordExerciseEntity insertIntoManagedObjectContext:self.managedObjectContext];


            newRecordExercise.recExerciseName = exNameLabel.text;
            [prevRecordWorkout addRecExercisesObject:newRecordExercise];

            RecordSet *newRecordSet = (RecordSet *)[[NSManagedObject alloc]
                                                    initWithEntity:recordSetEntity
                                                    insertIntoManagedObjectContext:self.managedObjectContext];

            newRecordSet.setLog = setStr;
            newRecordSet.weight = weight;
            newRecordSet.reps = reps;
            [newRecordExercise addSetsObject:newRecordSet];

        } else {

            RecordExercise *prevRecordExercise = [self.recordexercises objectAtIndex:0];

            if ([self.recordsets count] == 0) {

                RecordSet *newRecordSet = (RecordSet *)[[NSManagedObject alloc]
                                                        initWithEntity:recordSetEntity
                                                        insertIntoManagedObjectContext:self.managedObjectContext];

                newRecordSet.setLog = setStr;
                newRecordSet.weight = weight;
                newRecordSet.reps = reps;
                [prevRecordExercise addSetsObject:newRecordSet];

            } else {

                NSLog(@"Sets Already Imported");
            }
        }
    }

    NSError *errr;
    if (![self.managedObjectContext save:&errr])
    {
        NSLog(@"Error saving context: %@", errr);
    }
}

我有一种感觉,在使用组织得更好的代码之后,我可以实现我的目标。

感谢您提供的任何帮助。

附言。上面的代码在 logBu​​ttonPressed 方法中

4

1 回答 1

1

它可以简单得多。

1) 对于获取,只获取日期并让 Core Data 负责获取其他内容就足够了。效率更高,代码更少。要“获取”相关实体:

NSSet *workouts = date.workouts; 
NSSet *exercises = aWorkout.exercises;
NSSet *sets = anExercise.sets;

2)用于检查项目是否存在,例如日期只需遵循以下模式:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Date"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
       @"%K = %@", attributeName, theDateStringToBeChecked];
request.fetchLimit = 1;
NSArray *dates = [self.managedObjectContext executeFetchRequest:request];
NSManagedObject *objectToUse = dates.count ? dates[0] : [NSEntityDescription 
   insertNewObjectForEntityName:"Date" 
   inManagedObjectContext:self.managedObjectContext];

您可以通过构造一个接受实体字符串、属性字符串和要检查的值的方法来大大减少您的代码。它会有这样的原型:

-(NSManagedObject*)existingOrNewObjectWithEntityName:(NSString*)name
      attribute:(NSString*)attribute value:(NSString*)value;

因为您的对象是您的子类,所以NSManagedObject您可以简单地将它们转换为正确的类型。

最后,不要忘记调用[self.managedObjectContext save:&error];以保留您的更改。

于 2013-08-26T07:31:47.867 回答