Использование NSValueTransformer для установки значений экземпляра NSManagedObject - PullRequest
3 голосов
/ 10 июня 2011

Я использую пользовательский NSValueTransformer для хранения информации о цвете в моем Базовом хранилище данных.Преобразование между преобразуемыми данными и экземпляром UIColor прекрасно работает, когда данные о цветах уже находятся в хранилище (т. Е. После того, как приложение было запущено и завершило работу уже один раз).Однако, когда я впервые запускаю приложение и загружаю эти значения (из текстового файла), они «застряли» как NSCFStrings.

В этой строке кода «атрибуты» словарь имеет ключи, которые являются именами атрибутов NSManagedObjectи значения, которые являются ожидаемыми значениями для этих атрибутов.В моем примере цвета пара ключ-значение «color»: «1,1,1,0.5»

[object setValue:[attributes valueForKey:attribute] forKey:attribute];

Значение «color» теперь будет оставаться строкой в ​​этом случае, пока не будет преобразовано с помощьюмой NSValueTransformer и затем повторно преобразован в UIColor, когда приложение запускается снова.

Я мог бы просто сделать то же самое преобразование здесь, что я делаю в NSValueTransformer, но это в служебном классе, который я написал, который теоретически могиспользоваться для любого трансформатора.Я также подумал о том, чтобы найти способ вытащить из памяти все вновь созданные экземпляры NSManagedObject, тем самым вынудив преобразование пройти, но это выглядит как хак.

Примечание: этот "хак" работает для меня, и давайте продолжим, но все еще чувствую себя ужасно.Используйте метод сброса NSManagedObjectContext, если у вас есть похожие проблемы или вы ищете решение «просто работа».

Любые идеи?

(У меня есть догадка, это похоже на " Почемумой трансформируемый атрибут Core Data не использует мой собственный NSValueTransformer?", но за пределами заголовка наши проблемы кажутся другими)

Вот мой NSValueTransformer

@implementation UIColorRGBValueTransformer

+ (Class)transformedValueClass
{
    return [NSData class];
}

+ (BOOL)allowsReverseTransformation
{
    return YES;
}

- (id)transformedValue:(id)value
{
    return [value dataUsingEncoding:NSUTF8StringEncoding];
}

- (id)reverseTransformedValue:(id)value
{
    NSString *colorAsString = [[[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding] autorelease];
    NSArray *components = [colorAsString componentsSeparatedByString:@","];
    CGFloat r = [[components objectAtIndex:0] floatValue];
    CGFloat g = [[components objectAtIndex:1] floatValue];
    CGFloat b = [[components objectAtIndex:2] floatValue];
    CGFloat a = [[components objectAtIndex:3] floatValue];
    return [UIColor colorWithRed:r green:g blue:b alpha:a];

    return nil;
}

@end

1 Ответ

0 голосов
/ 10 июня 2011

Вы действительно не используете трансформируемый атрибут, как задумано.Ваш метод должен работать в теории, но это безобразный ключ.

Обычно вам нужно написать собственный преобразователь значения для определенного классом системы, когда вы хотите сделать что-то нестандартное.В подавляющем большинстве случаев предпочтительным методом является использование по умолчанию NSKeyedUnarchiveFromDataTransformerName .Любой класс, который реализует протокол NSCoding, может использовать этот преобразователь значения.

Так как UIColor действительно реализует протокол NSCoding, вы можете просто установить атрибут «преобразуемый», и NSKeyedUnarchiveFromDataTransformerName автоматически заполнит имя преобразователя (по крайней мере, это было в Xcode 3.x.) При использовании,Core Data создаст соответствующие средства доступа, так что вы можете установить и получить атрибут UIColor, как и любой другой ключ:

[aMoObject setValue:aUIcolorObj forKey:@"colorAttributeName"];

Как хорошее практическое правило, API сделает большую часть работы за вас вслучай классов API.Если вы усердно работаете с системным классом, возможно, вы что-то упустили.

...