Сохранение [UIColor colorWithPatternImage: image] UIColor в базовых данных с использованием NSKeyedArchiver - PullRequest
2 голосов
/ 17 сентября 2011

Я не могу создать объект NSData из UIColor (с шаблоном), созданного с помощью фабричного метода

[UIColor colorWithPatternImage:image]

отлично работает для стандартных объектов UIColor. Хотите знать, есть ли другой способ сохранить UIColor с шаблоном в Core Data.

Я использую следующий код для архивирования UIColor (с шаблоном) ...

- (id)transformedValue:(id)value {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
return data;

}

и вот ошибки, которые я получаю ...

-[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only support RGBA or the White color space, this method is a hack.'

Ответы [ 3 ]

6 голосов
/ 20 сентября 2011

О, да!Я понял.С огромной помощью следующих людей / сообщений ...

Дала мне идею использовать связанные объекты

Объяснение связанных объектов

и метод swizzling

Создайте категорию на UIColor.Используйте Associated Object, чтобы установить ссылку на изображение шаблона в экземпляре UIColor (вроде как динамическое свойство), не забудьте импортировать <objc/runtime.h>.Когда вы создаете свой UIColor color = [UIColor colorWithPatternImage:selectedImage], также установите связанный объект на цвет [color setAssociatedObject:selectedImage].

Затем реализуйте пользовательские методы encodeWithCoder и initWithCoder в категории для сериализации UIImage.

И, наконец, выполните несколько методов в файле main.m, чтобы вы могли вызывать оригинальные методы UIColor encodeWithCoder и initWithCoder из вашей категории UIColor.Тогда вам даже не нужно писать собственный Value Transformer для Core Data, потому что UIColor реализует протокол NSCoding.Код ниже ...

UIColor + patternArchive

#import "UIColor+patternArchive.h"
#import <objc/runtime.h>

@implementation UIColor (UIColor_patternArchive)

static char STRING_KEY; // global 0 initialization is fine here, no 
                        // need to change it since the value of the
                        // variable is not used, just the address

- (UIImage*)associatedObject 
{ 
    return objc_getAssociatedObject(self,&STRING_KEY); 
} 

- (void)setAssociatedObject:(UIImage*)newObject 
{ 
    objc_setAssociatedObject(self,&STRING_KEY,newObject,OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

- (void)encodeWithCoderAssociatedObject:(NSCoder *)aCoder 
{ 
    if (CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor))==kCGColorSpaceModelPattern) 
    { 
        UIImage *i = [self associatedObject]; 
        NSData *imageData = UIImagePNGRepresentation(i);
        [aCoder encodeObject:imageData forKey:@"associatedObjectKey"]; 
        self = [UIColor clearColor]; 
    } else {

        // Call default implementation, Swizzled
        [self encodeWithCoderAssociatedObject:aCoder];
    }
}

- (id)initWithCoderAssociatedObject:(NSCoder *)aDecoder 
{ 
    if([aDecoder containsValueForKey:@"associatedObjectKey"])
    { 
        NSData *imageData = [aDecoder decodeObjectForKey:@"associatedObjectKey"];
        UIImage *i = [UIImage imageWithData:imageData];
        self = [[UIColor colorWithPatternImage:i] retain]; 
        [self setAssociatedObject:i]; 
        return self; 
    } 
    else 
    { 
        // Call default implementation, Swizzled
        return [self initWithCoderAssociatedObject:aDecoder];
    } 
}

main.m

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "UIColor+patternArchive.h"

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Swizzle UIColor encodeWithCoder:
    Method encodeWithCoderAssociatedObject = class_getInstanceMethod([UIColor class], @selector(encodeWithCoderAssociatedObject:));
    Method encodeWithCoder = class_getInstanceMethod([UIColor class], @selector(encodeWithCoder:));
    method_exchangeImplementations(encodeWithCoder, encodeWithCoderAssociatedObject);

    // Swizzle UIColor initWithCoder:
    Method initWithCoderAssociatedObject = class_getInstanceMethod([UIColor class], @selector(initWithCoderAssociatedObject:));
    Method initWithCoder = class_getInstanceMethod([UIColor class], @selector(initWithCoder:));
    method_exchangeImplementations(initWithCoder, initWithCoderAssociatedObject);

    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}
1 голос
/ 18 сентября 2011

Поскольку UIColor реализует протокол NSCoding, вам не нужно писать свой собственный преобразователь, а можно просто указать Core Data использовать преобразование NSKeyedUnarchiveFromDataTransformerName (по умолчанию).

Насколько мне известно,это преобразование обрабатывает шаблоны в объектах UIColor.

0 голосов
/ 21 мая 2012

Я уверен, что есть способ конвертировать uicolor в шестнадцатеричные строки, вы можете просто сохранить шестнадцатеричную строку с «NSString» в базовой модели данных.

Как я могу преобразовать шестнадцатеричную строку RGB в UIColor в target-c?

...