CoreData瞬态关系示例

时间:2013-04-29 13:54:45

标签: ios objective-c core-data relationship transient

有没有人在CoreData中如何建模和编码 瞬态 到一个关系?例如,我有2个具有一对多关系的实体。医生和预约。现在我想在医生实体上建立一个名为mostRecentAppointment的瞬态关系。在xcode设计器中进行建模很简单,但我不确定实现方面。我也应该实现逆?看起来很傻。

4 个答案:

答案 0 :(得分:4)

看看我最近编写的代码,将图像缓存在NSManagedObject中:

首先在模型中定义瞬态属性(请注意,如果您的瞬态属性指向CoreData支持的对象类型以外的对象类型,则将其保留为“Undefined”模型)

enter image description here

然后,您为该实体重新生成NSManagedObject子类,或者只是手动添加新属性,头文件应如下所示:

@interface Card : NSManagedObject

@property (nonatomic, retain) NSString * imagePath;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * order;
@property (nonatomic, retain) NSString * displayName;
@property (nonatomic, retain) UIImage *displayImage;

@end

这里我们将transient属性的类更改为实际的类类型

e.g。此处displayImage类型为UIImage

在实现文件(或扩展类)中,为瞬态属性实现getter / setter:

-(UIImage*)displayImage{

  //Get Value
  [self willAccessValueForKey:@"displayImage"];
  UIImage *img = (UIImage*)[self primitiveValueForKey:@"displayImage"];
  [self didAccessValueForKey:@"displayImage"];

   if (img == nil) {
    if ([self imagePath]) { //That is a non-transient property on the object
      img = [UIImage imageWithContentsOfFile:self.imagePath];
      //Set Value
      [self setPrimitiveValue:img forKey:@"displayImage"];
    }
  }
  return img;
}

希望对你有所帮助。

答案 1 :(得分:2)

您需要做的是添加名为newAppointment的Appointment类型的实体,并在每次为给定医生创建新约会时设置此项。就这么简单。

总是实现逆向,因为苹果建议将其用于验证和核心数据效率。

或者,您可以为约会添加时间戳,并使用NSPredicates搜索给定Doctor的链接约会中的最新约会。

答案 2 :(得分:0)

嗯,您只需要在自己的示例程序中尝试一下,设置正确不超过一小时。

我的猜测是 - 不需要额外的编码。如果Apple在CoreData上的文档是正确的,那么普通属性/关系和"瞬态"之间的唯一区别就是一个是后者不是持久的,这意味着,当你" save"它不会更新持久存储。

我猜想,否则它的所有方面都是完整的,还有KVO / KVC合规性,撤消支持,验证以及删除规则的自动更新。唯一的事情是,在对实体进行新的获取后 - 瞬态关系将始终为零。

为此 - 我当然不会建议建立一个瞬态关系作为&#34;非可选&#34;,因为对于大多数实体来说,它很可能在大多数情况下为空。< / p>

我会设置一个反向关系(瞬态也明智地命名)并且删除规则都是&#34; Nullify&#34;。

到目前为止是暂时的关系。

但这是我提出的另一种选择,试图解决几乎相同的问题。我的预约&#34;是相关的任命之一,但不仅仅是最新的#34;而是第一个&#34;未完成的&#34;一。非常相似的逻辑。

我没有为瞬态关系添加新的计算属性给我的医生&#34;实体生成NSManagedObject子类,在类别中,如下所示:

@interface XXDoctor (XXExtensions)
/**
 @brief Needs manual KVO triggering as it is dependent on a collection. 
        Alternatively, you can observe insertions and deletions of the appointments, and trigger KVO on this propertyOtherwise it can be auto-
 @return the latest of the to-many appointments relation.
 **/
@property (readonly) XXAppointment *latestAppointment;    // defined as the
@end

实现:

#import "XXDoctor".h"
#import "XXAppointment.h"
@implementation XXDoctor (XXExtensions)
// this won't work because "appointments" is a to-many relation.
//+ (NSSet *)keyPathsForValuesAffectingLatestAppointment {
//  return [NSSet setWithObjects:@"appointments", nil];
//}
- (XXAppointment *) latestAppointment {
    NSInteger latestAppointmentIndex = [self.appointments indexOfObjectPassingTest:^BOOL(XXAppointment *appointment, NSUInteger idx, BOOL *stop) {
        *stop =  (appointment.dateFinished == nil);
        return *stop;
    }];
    return (latestAppointmentIndex == NSNotFound) ? nil : [self.appointments objectAtIndex: latestAppointmentIndex];
}
@end

答案 3 :(得分:0)

在这种情况下,适当的覆盖方法是-awakeFromFetch实体中的Doctor,例如:

- (void)awakeFromFetch {
    [super awakeFromFetch];// important: call this first!
    self.mostRecentAppointment = <something>; // normal  relationship
    self.mostRecentAppointment.doctor = self; // inverse relationship
}

在模型设计器中,将法线和逆向关系都标记为瞬态。应该是这样。