我在设置模型对象时遇到问题,无法将用户生成的CALayers的可视状态保存在iphone的简单图形应用程序中。
我试图通过将这些属性传递给实现NSCoding协议的模型对象,然后传递到app delegate拥有的NSMutableArray,来保存屏幕上所有当前图层的背景颜色和框架。然后我用NSKeyedArchiver归档数组并将其存储在NSUserDefaults中。
每个CALayer的backgroundColor属性都转换为UIColor,由模型对象进行编码以进行存储。我认为我正确地解析了数组或者没有正确地从unarchived数据中恢复状态。当我尝试访问存储在模型对象中的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
非常感谢任何帮助。我几乎是个菜鸟。我正在编码,存档和解析NSArray的NSNrray,它们从颜色的浮动中转换成几乎相同的方式并且访问不良。
答案 0 :(得分:3)
您当然希望在initWithCoder中保留颜色:
color = [[coder decodeObjectForKey:@"color"] retain];
或者,使用点语法将颜色声明为保留属性:
self.color = [coder decodeObjectForKey:@"color"];
答案 1 :(得分:0)
你过度释放layerColor
:你不拥有它(layerDataObject
确实如此),但你正在释放它。
答案 2 :(得分:0)
看起来NSCoder for iPhone无法响应-encodeWithCGRect: