2

我在设置模型对象以在 iphone 的简单图形应用程序中保存用户生成的 CALayers 的视觉状态时遇到问题。

我试图通过将这些属性传递给实现 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];

或者,使用点语法作为颜色被声明为保留属性:

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

你过度释放layerColor:你不拥有它(layerDataObject确实),但你正在释放它。

于 2009-07-25T19:37:11.943 回答
0

看起来 iPhone 的 NSCoder 没有响应-encodeWithCGRect:

来源:http: //17.254.2.129/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSCoder_Class/Reference/NSCoder.html

于 2009-07-26T23:30:26.210 回答