当多对面的NSManagedObject子类发生更改时,如何更新NSManagedObject子类?

时间:2014-07-20 20:54:26

标签: ios core-data

我想在“Day”中维护正确的emoAvg。这是我正在寻找的目标:

  1. 每当“情感”与之相关时,都会更新“日”的emoAvg “日子”......一天可以有很多情绪。
  2. 每当从“Day”中删除“Emotion”时更新“Day”的emoAvg
  3. 每当“情感”的情感属性发生变化时,都会更新“日”的emoAvg。
  4. enter image description here

    我希望将所有这些代码保存在模型层中,并且我已经能够通过调用以下代码将情感与日子连接起来,这些代码将情感创建时的情感附加到情感日。

    我无法为“Day”与“Emotion”的多对多关系编写自定义访问器。我坚持使用Xcode 4.6.2并且此版本中似乎不存在复制/粘贴客户ObjectiveC访问器功能。

    构建此代码的好方法是什么?

     - (void)setDate:(NSDate *)date
    {
        [self willChangeValueForKey:@"date"];
        [self setPrimitiveValue:date forKey:@"date"];
    
        [self associateDay];
    
        [self didChangeValueForKey:@"date"];
    
    }
    
    -(void)associateDay
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
        [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    
        NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:self.date];
    
        //Start of Day
        [dateComponents setHour:0];
        [dateComponents setMinute:0];
        [dateComponents setSecond:0];
        NSDate *startOfDay = [calendar dateFromComponents:dateComponents];
        //NSLog(@"Start of Day:       %@", [dateFormatter stringFromDate:startOfDay]);
    
        //End of Day
        [dateComponents setHour:23];
        [dateComponents setMinute:59];
        [dateComponents setSecond:59];
        NSDate *endOfDay = [calendar dateFromComponents:dateComponents];
        //NSLog(@"End of Day:         %@", [dateFormatter stringFromDate:endOfDay]);
    
        //Find all Day Entities that fall on the same calendar date
        NSPredicate *datePredicate = [NSPredicate predicateWithFormat:@"date > %@ AND date < %@", startOfDay, endOfDay];
        NSFetchRequest *fetchDays = [[NSFetchRequest alloc]initWithEntityName:@"Day"];
        fetchDays.predicate = datePredicate;
        NSManagedObjectContext *context = [(id)[UIApplication sharedApplication].delegate managedObjectContext];
        NSArray *daysFound = [context executeFetchRequest:fetchDays error:nil];
    
        if ([daysFound count] == 1)
        {
            Day *dayWithMatchingDate = [daysFound objectAtIndex:0];
            self.day = dayWithMatchingDate;
            NSLog(@"Found %d matching days",[daysFound count]);
        }
    
        if ([daysFound count] > 1)
        {
            NSLog(@"Found %d matching days...Something needs fixing",[daysFound count]);
        }
    
        if ([daysFound count] < 1)
        {
            NSLog(@"Found %d matching days...Making a new Day and associating it",[daysFound count]);
            NSManagedObjectContext *context = [(id)[UIApplication sharedApplication].delegate managedObjectContext];
            Day *newDay = [NSEntityDescription insertNewObjectForEntityForName:@"Day" inManagedObjectContext:context];
            newDay.date = self.date;
            self.day = newDay;
        }
    }
    

2 个答案:

答案 0 :(得分:0)

我认为将Day建模为数据模型的一部分并不一定是个好主意。现有的日期属性应足以用于选择,过滤和其他逻辑。

然而,你走在正确的轨道上。关键是要覆盖设置者。您需要在EmotionDay中覆盖以下设置器(我的提示:在情感Emotion+Additions上创建类别,以使此代码与基本模型类分开)。

    setEmotion
  1. EmotionremoveEmotionsObject
  2. DayaddEmotionsObject
  3. Day

    e.g。

    -(void)removeEmotionsObject:(Emotion)value {
        NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
        [self willChangeValueForKey:@"emotions" 
            withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
        [[self primitiveEmotions] removeObject:value];
        [self didChangeValueForKey:@"emotions" 
            withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    }
    

    核心数据编程指南的relevant section中有关这些访问者的更多详细信息。

答案 1 :(得分:0)

我能够获得我要求工作的代码。 然而,这是一个混乱的混乱,我认为最好与NSNotificationCenter合作,并观察相关对象的变化。 这是有效的代码。 要给Mundi提供帮助我的道具。

- (void)addEmotionsObject:(Emotion *)value
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:@"emotions" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];

    [[self primitiveEmotions] addObject:value];

    [self calculateEmotionalAverage];

    [self didChangeValueForKey:@"emotions" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
}

- (void)removeEmotionsObject:(Emotion *)value
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:@"emotions" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];

    [[self primitiveEmotions] removeObject:value];

    [self calculateEmotionalAverage];

    [self didChangeValueForKey:@"emotions" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
}



- (void)addEmotions:(NSSet *)value
{
    [self willChangeValueForKey:@"emotions" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];

    [[self primitiveEmotions] unionSet:value];

    [self calculateEmotionalAverage];

    [self didChangeValueForKey:@"emotions" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
}



- (void)removeEmotions:(NSSet *)value
{
    [self willChangeValueForKey:@"emotions" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];

    [[self primitiveEmotions] minusSet:value];

    [self calculateEmotionalAverage];

    [self didChangeValueForKey:@"emotions" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
}


-(void)calculateEmotionalAverage
{
    float emotionalTotal = 0;
    for (Emotion *emo in self.emotions)
    {
        if ([emo.emotion isEqualToString:@"Joy = 22"]){
            emotionalTotal += 22.0;
        }
        NSLog(@"%f",emotionalTotal);
    }
}