代码之家  ›  专栏  ›  技术社区  ›  aaronium112

当一个或多个相关的NSManagedObject子类发生更改时,如何更新NSManagedObjects子类?

  •  0
  • aaronium112  · 技术社区  · 10 年前

    我想在“Day”中保持正确的表情。以下是我希望实现的目标:

    1. 每当“情绪”与 “天”。。。一天可以有很多情绪。
    2. 每当“情绪”从“日”中删除时,更新“日”的emoAvg
    3. 每当“情绪”的情绪属性发生变化时,更新“日”的情绪平均值。

    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 回复  |  直到 10 年前
        1
  •  0
  •   Mundi    10 年前

    我认为,对 Day 作为数据模型的一部分。现有的日期属性应该足以用于选择、筛选和其他逻辑。

    然而,你走在了正确的轨道上。关键是覆盖设置器。您需要重写以下setter Emotion 白天 (我的提示:创建 类别 论情感 Emotion+Additions 保持该代码与基本模型类分离)。

    1. setEmotion 在里面 强烈的感情
    2. removeEmotionsObject 在里面 白天
    3. addEmotionsObject 在里面 白天

    例如

    -(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 核心数据编程指南。

        2
  •  0
  •   aaronium112    10 年前

    我能够得到我要求的代码。 然而,这是一个混乱的局面,我认为最好与NSNotificationCenter合作,观察相关对象的变化。 这是有效的代码。 我得给蒙迪一些支持,因为他帮助了我。

    - (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);
        }
    }