【问题标题】:How to store CGRect and other things in core data如何在核心数据中存储 CGRect 和其他东西
【发布时间】:2010-10-11 17:49:00
【问题描述】:

我在使用 coredata 时遇到了一些初期问题,但如果有人可以向我解释一些简单的案例,我觉得这对我来说会很清楚。

我想将我的模型放入 coredata,并在最简单的情况下利用撤消/重做。问题是,我看到的所有示例都倾向于存储字符串或整数。如果我有一个想要在核心数据中实现的类(一个虚构的例子)怎么办:

@interface Badge : NSObject {

NSString *textForBadge;
int      badgeValue;
UIColor  *color;
CGRect    rect;
NSMutableArray *awards; // this would be a list of 'Category' - another custom class
}

这些都是当场编造出来的,但每一个都凸显了一个困惑

如我所见,我将打开 .xcdatamodel 并添加一个名为“Badge”的新实体,即NSManagedObject。然后我为textForBadge 添加一个String 类型的属性。到现在为止还挺好。我为 badgeValue 做了类似的事情,但后来来到 UIColorCGRect,我有点难过,因为它们没有属性。我是否应该创建一个实体来表示每个整数(即具有四个属性x,y,w,hRect 实体)?然后每次都用这些整数填充一个 CGRect ? UIColor 也一样?

最后,我来到了我的awards 列表。如果这些是指向代表奖项的多个对象的指针列表,它们可能包含图像、颜色、文本等。我​​假设award 将再次成为我必须设计的实体,而不是Badge 存储数组我会从它到 Award 类有一对多的关系。

我做对了这件事,还是朝着相反的方向前进?我看到的所有示例都对像 String 或 int 这样的普通对象进行操作,因此希望在实现一堆东西之前确保我脑子里有这个。

亲切的问候,

布林

【问题讨论】:

    标签: iphone objective-c core-data ios4


    【解决方案1】:

    特别是关于CGRect,您可以使用NSStringFromCGRectCGRect 存储为NSString。 然后使用CGRectFromString 将其转换回来:

    CGRect rect = CGRectMake( 5, 5, 40, 30 );
    NSString* rectAsString = NSStringFromCGRect( rect );
    CGRect original = CGRectFromString( rectAsString );
    

    这使您可以轻松地将其存储在 NSManagedObject 中。 然后你可以在你的实现中添加一个自定义访问器来转换它:

    - (CGRect)realRect {
        return CGRectFromString( self.rectAsString );
    }
    

    【讨论】:

      【解决方案2】:

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

      在模型中将对象定义为可变形:

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

      @property (nonatomic, retain) UIColor *foreground;
      
      textView.textColor = element.foreground;
      

      在 NSValue 对象中包装 CGRect 结构:

      @property (nonatomic, retain) NSValue *imageRect;
      
      CGRect imageRect = [self.imageRect CGRectValue];
      imageRect.size.width = 100;
      self.imageRect = [NSValue valueWithCGRect:imageRect];
      

      【讨论】:

      • 这是做这类事情的推荐方法
      【解决方案3】:

      如果你使用 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);
      

      会输出

      test1: 0.000000 0.000000 0.000000 0.000000
      test2: -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000 -344800963262078397207103271862272.000000
      

      我认为最好分别存储四个值。

      【讨论】:

        【解决方案4】:

        这是相关文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html 但本质上,您必须为 Core Data 提供一种方法,以便在您的非标准属性和它可以存储的内容类型之间进行转换。有两种方法可以做到这一点。要么使用可转换的属性和值转换器,要么使用瞬态属性并仅在要保存托管对象上下文时进行转换。

        我认为在大多数情况下,您所描述的内容(定义自定义实体来存储类似 CGRect 的组件)是多余的。

        【讨论】:

        • 您在此处引用的链接已失效。 @AndrewMadsen
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-05
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 2018-07-18
        • 2011-08-24
        相关资源
        最近更新 更多