2011-09-17 2 views
2

を使用してコアデータにUIColorは保存[UIColor colorWithPatternImage:画像]私はファクトリメソッドを使用して作成(パターン)UIColorからNSDataオブジェクトを作成することができませんよNSKeyedArchiver

[UIColor colorWithPatternImage:image]

のため正常に動作します標準のUIColorオブジェクトです。コアデータにパターンを含むUIColorを保存する別の方法があるかどうかが気になります。私は(パターン)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.' 

答えて

5

ああはい!わかった。以下の人々/ポストから多くの援助と...

Gave me the idea to use associatedObjects

Explanation of associatedObjects

and method swizzling

UIColorのカテゴリを作成します。関連付けられたオブジェクトを使用して、UIColorインスタンスのパターンイメージ(ダイナミックプロパティのようなもの)への参照を設定します。<objc/runtime.h>をインポートすることを忘れないでください。 UIColor color = [UIColor colorWithPatternImage:selectedImage]を作成するときには、関連するオブジェクトも色[color setAssociatedObject:selectedImage]に設定します。

次に、カスタムencodeWithCoderメソッドとinitWithCoderメソッドをカテゴリに実装して、UIImageをシリアル化します。

最後に、UIColorカテゴリ内から元のUIColorのencodeWithCoderメソッドとinitWithCoderメソッドを呼び出すことができるように、main.mファイルにいくつかのメソッドをスウィズします。 UIColorがNSCodingプロトコルを実装しているため、独自のValue Data Transformer for Core Dataを作成する必要はありません。以下のコード...

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

素晴らしい...あなたは私の一日を作りました...ありがとう – Ankur

1

UIColorはNSCodingプロトコルを実装しているので、独自のトランスフォーマーを作成する必要はありませんが、コアデータにNSKeyedUnarchiveFromDataTransformerNameトランスフォームを使用するように指定することができます(デフォルト)。

私の知る限り、その変換はUIColorオブジェクトのパターンを処理します。

+0

それでも興味深いあなたがいずれかを指定しない場合にコアデータは、デフォルト値の変圧器を使用することにかかわらず、機能していません。これは、標準のUIColorオブジェクトで動作しますが、パターン付きのUIColorオブジェクトに対しても同じエラーが発生します。 –

+0

私はエラーを二重にしました。バグのように見えます。 – TechZen

+0

お試しいただきありがとうございます –

関連する問題