2

モデル オブジェクトをセットアップして、ユーザーが生成した CALayers のビジュアル状態を iPhone 用の単純なグラフィック アプリケーションに保存するのに問題があります。

現在のすべてのレイヤーの背景色とフレームを画面に保存しようとしています。これらのプロパティを NSCoding プロトコルを実装するモデル オブジェクトに渡し、次にアプリ デリゲートが所有する NSMutableArray に渡します。次に、NSKeyedArchiver を使用して配列をアーカイブし、NSUserDefaults に保存します。

各 CALayer の backgroundColor プロパティは UIColor に変換され、モデル オブジェクトによってエンコードされて格納されます。配列のアーカイブを正しく解除していないか、アーカイブされていない配列から状態を正しく復元していないと思います。モデル オブジェクトに格納されている UIColor オブジェクトにアクセスしようとすると、EXC_BAD_ACCESS が返されます。

おそらくUIColorオブジェクトのエンコードのバグだと思ったので、CGColorGetComponents関数でCGColorRefから値を取り出して配列に格納してエンコードしてアーカイブしようとしましたが、アーカイブ解除後のアクセス不良の結果は同じだったので、私は私はそれを間違っているだけです。

これは私のモデルオブジェクトです:

@interface AILayerData : NSObject <NSCoding> {

    UIColor*    color;
    CGRect      frame;
}

@property (retain) UIColor* color;
@property (assign) CGRect   frame;

@end


@implementation AILayerData

@synthesize color;
@synthesize frame;

- (void)encodeWithCoder:(NSCoder *)coder; 
{
    [coder encodeObject:color forKey:@"color"];
    [coder encodeCGRect:frame forKey:@"frame"];
}


- (id)initWithCoder:(NSCoder *)coder;
{
    self = [[AILayerData alloc] init];
    if (self != nil)
    {
        color = [coder decodeObjectForKey:@"color"];
        frame = [coder decodeCGRectForKey:@"frame"];
    }
    return self;
}

@end

そして、これは私のアーカイブの実装です:

@implementation AppDelegate

- (void)applicationWillTerminate:(UIApplication *)application {

    NSArray *layersArray = viewController.view.layer.sublayers;

    dataArray = [NSMutableArray array]; 

    for(AILayer *layer in layersArray)
    {
        AILayerData *layerData = [[AILayerData alloc] init];

        layerData.frame = layer.frame;

        UIColor *layerColor = [UIColor colorWithCGColor:layer.backgroundColor];

        layerData.color = layerColor;               

        [dataArray addObject:layerData];

        [layerData release];

    }

    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:layerDataArray] forKey:@"savedArray"];
}

@end

そして、ここで状態を復元します。

@implementation ViewController

- (void)viewDidLoad 
{    
    [super viewDidLoad];

    spaceView = [[AISpaceView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.view = spaceView;

    [spaceView release];

    spaceView.delegate = self;

    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];

    NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];

    if (dataRepresentingSavedArray != nil) {

        [self restoreStateWithData:dataRepresentingSavedArray];

    }
}

- (void)restoreStateWithData:(NSData *)data 
{   
    NSArray *savedLayers = [NSKeyedUnarchiver unarchiveObjectWithData:data];

    if (savedLayers != nil) {

        NSArray *restoredLayers = [[NSArray alloc] initWithArray:savedLayers];

        for(AILayerData *layerDataObject in restoredLayers) {                       

            UIColor *layerColor = layerDataObject.color;

            AILayer *newLayer = [[AILayer alloc] init];         

            newLayer.backgroundColor = layerColor.CGColor;

            newLayer.frame = layerDataObject.frame;         

            newLayer.isSelected = NO;

            [self.view.layer addSublayer:newLayer];

            [newLayer release];                                 
        }

        [restoredLayers release];

        [spaceView.layer layoutSublayers];      
    }
}

@end

これに関するヘルプは大歓迎です。私はほとんど初心者です。色のフロートから変換された NSNumbers の NSArray をほぼ同じ方法でエンコード、アーカイブ、およびアンアーカイブしていて、アクセスが悪くなりました。

4

3 に答える 3

3

確かに initWithCoder で色を保持したい:

color = [[coder decodeObjectForKey:@"color"] retain];

または、 color が保持プロパティとして宣言されているため、ドット構文を使用します。

self.color = [coder decodeObjectForKey:@"color"];
于 2009-07-26T10:31:17.430 に答える
0

NSCoder for iPhone が応答しないようです-encodeWithCGRect:

ソース: http://17.254.2.129/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSCoder_Class/Reference/NSCoder.html

于 2009-07-26T23:30:26.210 に答える