使用 NSKeyedArchiver 将 [UIColor colorWithPatternImage:image] UIColor 保存到核心数据 [英] Saving [UIColor colorWithPatternImage:image] UIColor to Core Data using NSKeyedArchiver

查看:21
本文介绍了使用 NSKeyedArchiver 将 [UIColor colorWithPatternImage:image] UIColor 保存到核心数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法从使用工厂方法创建的 UIColor(带有模式)创建 NSData 对象

[UIColor colorWithPatternImage:image]

适用于标准 UIColor 对象.想知道是否有另一种方法可以将带有图案的 UIColor 保存到 Core Data 中.

我正在使用以下代码来存档 UIColor(带有图案)...

- (id)transformedValue:(id)value {NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];返回数据;

}

这些是我收到的错误...

-[NSKeyedArchiver dealloc]: 警告:NSKeyedArchiver 在没有调用 -finishEncoding 的情况下被释放.由于未捕获的异常NSInternalInconsistencyException"而终止应用程序,原因:仅支持 RGBA 或白色颜色空间,此方法是一种技巧."

解决方案

哦是的!我知道了.在以下人员/帖子的帮助下...

给了我使用关联对象的想法

相关对象的说明

和方法调配

在 UIColor 上创建一个类别.使用关联对象设置对 UIColor 实例中图案图像的引用(有点像动态属性),不要忘记导入 .创建 UIColor color = [UIColor colorWithPatternImage:selectedImage] 时,还要在颜色 [color setAssociatedObject:selectedImage] 上设置关联对象.

然后在category中实现自定义encodeWithCoder和initWithCoder方法来序列化UIImage.

最后在 main.m 文件中做一些方法调整,这样你就可以从你的 UIColor 类别中调用原始的 UIColor encodeWithCoder 和 initWithCoder 方法.然后你甚至不需要为 Core Data 编写你自己的 Value Transformer,因为 UIColor 实现了 NSCoding 协议.下面的代码...

UIColor+patternArchive

#import "UIColor+patternArchive.h"#import 

<代码>@implementation UIColor (UIColor_patternArchive)静态字符 STRING_KEY;//全局 0 初始化在这里没问题,没有//需要改变它,因为它的值//不使用变量,只使用地址- (UIImage*)相关对象{返回 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 = [自关联对象];NSData *imageData = UIImagePNGRepresentation(i);[aCoder encodeObject:imageData forKey:@"associatedObjectKey"];self = [UIColor clearColor];} 别的 {//调用默认实现,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] 保留];[self setAssociatedObject:i];回归自我;}别的{//调用默认实现,Swizzled返回 [self initWithCoderAssociatedObject:aDecoder];}}

main.m

#import #import #import "UIColor+patternArchive.h"

<代码>int main(int argc, char *argv[]){NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];//混合 UIColor encodeWithCoder:方法 encodeWithCoderAssociatedObject = class_getInstanceMethod([UIColor class], @selector(encodeWithCoderAssociatedObject:));方法 encodeWithCoder = class_getInstanceMethod([UIColor class], @selector(encodeWithCoder:));method_exchangeImplementations(encodeWithCoder, encodeWithCoderAssociatedObject);//混合 UIColor initWithCoder:方法 initWithCoderAssociatedObject = class_getInstanceMethod([UIColor class], @selector(initWithCoderAssociatedObject:));方法 initWithCoder = class_getInstanceMethod([UIColor class], @selector(initWithCoder:));method_exchangeImplementations(initWithCoder, initWithCoderAssociatedObject);int retVal = UIApplicationMain(argc, argv, nil, nil);[池释放];返回 retVal;}

I'm unable to create an NSData object from a UIColor (with a pattern) created with the factory method

[UIColor colorWithPatternImage:image]

works fine for standard UIColor objects. Wondering if there is another way to save a UIColor with a pattern into Core Data.

I am using the following code to archive the UIColor (with a pattern)...

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

}

and these are the errors I'm receiving...

-[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.'

解决方案

Oh Yes! I got it. With a lot of help from the following people/posts...

Gave me the idea to use associatedObjects

Explanation of associatedObjects

and method swizzling

Create a category on UIColor. Use an Associated Object to set a reference to the pattern image in the UIColor instance (kind of like a dynamic property), don't forget to import <objc/runtime.h>. When you create your UIColor color = [UIColor colorWithPatternImage:selectedImage], also set the associated object on the color [color setAssociatedObject:selectedImage].

Then implement custom encodeWithCoder and initWithCoder methods in the category to serialize the UIImage.

And finally do some method swizzling in the main.m file so you can invoke the original UIColor encodeWithCoder and initWithCoder methods from within your UIColor Category. Then you don't even need to write your own Value Transformer for Core Data because UIColor implements the NSCoding protocol. Code below...

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;
}

这篇关于使用 NSKeyedArchiver 将 [UIColor colorWithPatternImage:image] UIColor 保存到核心数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆