如何在核心数据中存储CGRect和其他东西

dav*_*ryn 12 iphone core-data objective-c ios4

我对coredata有一些初期的问题,但如果有人能向我解释一些简单的案例,我觉得这会让我感到非常清楚.

我想把我的模型放到coredata中,并且在最简单的情况下利用undo/redo.事实是,我看到的所有例子都倾向于存储字符串或整数.如果我想要在核心数据中实现如下的类(一个组成的示例),该怎么办?

@interface Badge : NSObject {

NSString *textForBadge;
int      badgeValue;
UIColor  *color;
CGRect    rect;
NSMutableArray *awards; // this would be a list of 'Category' - another custom class
}
Run Code Online (Sandbox Code Playgroud)

这些都是当场制作的,但每一个都突出了一个混乱

在我看来,我会打开.xcdatamodel并添加一个新的Entity caled'Badge',这将是一个NSManagedObject.然后我添加一个textForBadge类型的属性String.到现在为止还挺好.我做badgeValue类似的财产以后,但随后来到UIColorCGRect和我有点为难,因为没有这些属性.我是否应该创建一个实体来表示每个(即Rect具有四个属性的实体x,y,w,h)的实体?然后每次用这些整数填充CGRect?同样适用于UIColor?

最后,我来到我的清单awards.如果这些是指向表示奖励的多个对象的指针列表,则它们可能包含图像,颜色,文本等.我​​认为这award将再次成为我必须设计的实体而不是Badge存储数组我将拥有1从它到Award班级的许多关系.

我能做到这一点,还是在相反的方向竞争?我看到的所有示例都在像String或int这样的vanilla对象上运行,所以在实现一堆东西之前,我要确保在脑子里有这个权利.

亲切的问候,

布林

aeg*_*orz 23

具体关于CGRect你可以使用NSStringFromCGRect商店a CGRect作为NSString.然后用CGRectFromString它来转换回来:

CGRect rect = CGRectMake( 5, 5, 40, 30 );
NSString* rectAsString = NSStringFromCGRect( rect );
CGRect original = CGRectFromString( rectAsString );
Run Code Online (Sandbox Code Playgroud)

这使您可以轻松地将其存储在NSManagedObject中.然后,您可以在实现中添加自定义访问器以进行转换:

- (CGRect)realRect {
    return CGRectFromString( self.rectAsString );
}
Run Code Online (Sandbox Code Playgroud)


Sym*_*ric 17

在Core Data中存储像CGRect这样的UIColor对象和结构相当容易(这可能是新的,因为OP询问了它):

在模型中将对象定义为Transformable:

核心数据模型的快照

在NSManagedObject类中,通常定义和使用UIColor对象:

@property (nonatomic, retain) UIColor *foreground;

textView.textColor = element.foreground;
Run Code Online (Sandbox Code Playgroud)

在NSValue对象中包装CGRect结构:

@property (nonatomic, retain) NSValue *imageRect;

CGRect imageRect = [self.imageRect CGRectValue];
imageRect.size.width = 100;
self.imageRect = [NSValue valueWithCGRect:imageRect];
Run Code Online (Sandbox Code Playgroud)


tom*_*tom 9

如果使用aegzorz建议的NSStringFromCGRect序列化,则必须小心.对于在NSString表示中缩写的大数字,这不能可靠地工作.

例如,这段代码

CGRect test1 = CGRectMake(CGFLOAT_MAX, CGFLOAT_MAX, CGFLOAT_MAX, CGFLOAT_MAX);
NSString* test1Str = NSStringFromCGRect(test1);
CGRect test2 = CGRectFromString(test1Str);
NSLog(@"test1: %f %f %f %f", test1.origin.x - CGFLOAT_MAX, test1.origin.y - CGFLOAT_MAX, test1.size.width - CGFLOAT_MAX, test1.size.height - CGFLOAT_MAX);
NSLog(@"test2: %f %f %f %f", test2.origin.x - CGFLOAT_MAX, test2.origin.y - CGFLOAT_MAX, test2.size.width - CGFLOAT_MAX, test2.size.height - CGFLOAT_MAX);
Run Code Online (Sandbox Code Playgroud)

将输出

test1: 0.000000 0.000000 0.000000 0.000000
test2: -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000
Run Code Online (Sandbox Code Playgroud)

在我看来,最好分别存储这四个值.


And*_*sen 6

这是相关文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html但实质上,您必须提供一种方法让Core Data在您的非标准属性及其可存储的东西.有两种方法可以做到这一点.使用可转换属性和值转换器,或使用瞬态属性并仅在要保存托管对象上下文时执行转换.

我认为在大多数情况下,你所描述的(定义自定义实体来存储像CGRect这样的组件)是过度的.