Как хранить CGRect и другие вещи в основных данных - PullRequest
12 голосов
/ 11 октября 2010

У меня есть несколько проблем с прорезыванием зубов 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, но потом подхожу к UIColor и CGRect, и я немного озадачен, так как для них нет свойства. Должен ли я создать сущность для представления каждой (т.е. Rect сущности, которая имеет четыре свойства x,y,w,h), которые являются целыми числами? Затем каждый раз заполнять CGRect этими целочисленными значениями То же самое для UIColor?

Наконец, я попал в список awards. Если это список указателей на ряд объектов, представляющих награду, они могут содержать изображение, цвет, текст и т. Д. Я предполагаю, что award снова будет сущностью, которую я должен разработать, а не Badge, хранящей массив Я бы имел отношение 1 ко многим от него до Award класса.

Правильно ли я это понимаю или иду в противоположном направлении? Все примеры, которые я вижу, работают с ванильными объектами, такими как String или int, поэтому я хочу убедиться, что у меня есть это право, прежде чем реализовывать кучу вещей.

С уважением,

Брин

Ответы [ 4 ]

23 голосов
/ 12 октября 2010

В частности, CGRect вы можете использовать NSStringFromCGRect, хранить CGRect как NSString.Затем используйте CGRectFromString, чтобы преобразовать его обратно:

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

Это позволяет вам легко сохранить его в NSManagedObject.Затем вы можете добавить собственный аксессор в вашу реализацию, чтобы преобразовать его:

- (CGRect)realRect {
    return CGRectFromString( self.rectAsString );
}
17 голосов
/ 10 ноября 2013

Хранить объекты и структуры UIColor, такие как CGRect, в Core Data довольно легко (это может быть новым, поскольку об этом спросил ОП):

Определить объекты как трансформируемые в вашей модели:

snapshot of Core Data model

В классах NSManagedObject определяют и используют объекты UIColor обычно:

@property (nonatomic, retain) UIColor *foreground;

textView.textColor = element.foreground;

Обертывание структур CGRect в объект NSValue:

@property (nonatomic, retain) NSValue *imageRect;

CGRect imageRect = [self.imageRect CGRectValue];
imageRect.size.width = 100;
self.imageRect = [NSValue valueWithCGRect:imageRect];
9 голосов
/ 01 октября 2012

Вы должны быть осторожны, если используете сериализацию NSStringFromCGRect, предложенную aegzorz.Это не работает надежно для больших чисел, которые сокращаются в представлении 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

В моемМнение, что лучше хранить четыре значения отдельно.

6 голосов
/ 11 октября 2010

Это соответствующая документация: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html, но, по сути, вы должны предоставить Core Data возможность преобразовывать ваши нестандартные свойства в типы, которые они могут хранить.Есть два способа сделать это.Либо используйте трансформируемые атрибуты и преобразователи значений, либо используйте переходные свойства и выполняйте преобразование только тогда, когда будет сохранен контекст управляемого объекта.

В большинстве случаев я думаю, что вы описываете (определение пользовательских объектов для хранениякомпоненты чего-то вроде CGRect) является излишним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...