使用核心数据实现瞬态属性

Posted

技术标签:

【中文标题】使用核心数据实现瞬态属性【英文标题】:Implementing a Transient Property with Core Data 【发布时间】:2011-08-25 19:24:05 【问题描述】:

我想不通。我所读到的关于瞬态属性的内容告诉我,它们可以在对象模型中以未定义的类型来识别。但是编译器会抱怨这个错误,类型未知。

来自 Core Dat 编程指南:

如果不受支持的属性是一个对象,那么在托管对象模型中,您将其类型指定为未定义,并且它是瞬态的。当您实现实体的自定义类时,无需为属性添加实例变量——您可以使用托管对象的私有内部存储。关于下面描述的实现需要注意的一点是它们缓存了瞬态值。这使得访问价值更有效——这也是变更管理所必需的。如果定义自定义实例变量,则应在 didTurnIntoFault 中清理这些变量,而不是在 dealloc 或 finalize 中清理。

这是头文件:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class SearchTerms;

@interface SearchResult : NSManagedObject 
@private

@property (nonatomic, retain) NSString * lattitude;
@property (nonatomic, retain) NSString * details;
@property (nonatomic, retain) NSString * endTime;
@property (nonatomic, retain) NSString * longitude;
@property (nonatomic, retain) NSString * city;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * imageLink;
@property (nonatomic, retain) NSString * startTime;
@property (nonatomic, retain) UNKNOWN_TYPE coordinate;
@property (nonatomic, retain) UNKNOWN_TYPE subtitle;
@property (nonatomic, retain) SearchTerms * searchUsed;

@end

我正在尝试将 MKAnnotation 的属性包括标题、副标题和坐标。在这里,我需要从其他字段中导出字幕,并从经度和纬度中导出坐标。

我不确定如何协调指南所说的内容和看起来明显错误的内容,而编译器是这样说的。

一旦我获得了正确的标题,我就可以正确地实现,我将使用 awakeFromFault 来设置值。我不确定是否需要使用 didTurnIntoFault 释放字幕,这将是一个 NSString,但这似乎是指南所说的。

我还没有看到如何实现简单瞬态属性的真正好例子。我很想将属性添加到托管对象实体中,而忘记在托管对象模型中提及它。但如果我这样做,我似乎会忽略一些东西。

【问题讨论】:

【参考方案1】:

您需要将属性的类型更改为id,或者任何最合适的类型:

@interface SearchResult : NSManagedObject

@property (nonatomic, retain) id coordinate;
@end

另一种处理方式是通过 KVC 和依赖键:

@implementation SearchResult
+ (NSSet *) keyPathsForValuesAffectingCoordinate

  return [NSSet setWithObjects:@"latitude", @"longitude", nil];


- (id) coordinate

  // Derive the coordinate value

@end

【讨论】:

【参考方案2】:

这里的问题是 MKAnnotation 协议将其 coordinate 值存储在 CLLocationCoordinate2D 中,它不是对象而是结构,并且不支持键值编码。要将其用作过渡属性,您需要将其包装在一个对象中。

The Core Data Programming Guide: Scalar Value Constraints

如果您想使用不是其中之一的标量类型或结构 由 Core Data 直接支持,而不是其中一种结构 受键值编码支持,您必须将其存储在您的托管 对象作为对象——通常是一个 NSValue 实例,尽管你可以 还定义您自己的自定义类。然后,您将其视为对象 值,如本文后面所述。这取决于用户 对象从 NSValue(或自定义)中提取所需的结构 检索值时的对象,并将结构转换为 设置值时的 NSValue(或自定义)对象。

【讨论】:

假设你正在存储一个对象,但是:使用 Undefined 和 Transient 来避免在 Core Data 中持久化它是否合适?如果是这样,您应该如何处理那些UNKNOWN_TYPEs?用实际类型手动替换它们?

以上是关于使用核心数据实现瞬态属性的主要内容,如果未能解决你的问题,请参考以下文章

向核心数据实体添加瞬态属性是不是需要新版本模型?

核心数据,“按瞬态属性排序”解决方法

将属性更改为不再是瞬态的 - 我可以通过轻量级核心数据迁移来做到这一点吗?

核心数据:瞬态值脏对象

基于瞬态属性获取的结果控制器 sectionIndexTitle

dotnet 核心中的 Dbcontext 对象瞬态