How do I save state with CALayers?

2019-07-23 15:11发布

I have a simple iphone application that paints blocks using a subclass of CALayer and am trying to find the best way to save state or persist the currently created layers.

I tried using Brad Larson's answer from this previous question on storing custom objects in the NSUserDefaults, which worked for persisting my subclass of CALayer, but not it's basic state like geometry and background color, so they were there but did not render on relaunch.

I made my declared instance variables conform to the NSCoding protocol but do not know how to make CALayer's properties do the same without re-declaring all of it's properties. Or is this not the correct/best approach altogether?

Here is the code I'm using to archive the array of layers:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:viewController.view.layer.sublayers] forKey:@"savedArray"];

And here is the code I'm using to reload my layers in -viewDidLoad:

    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];

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

if (dataRepresentingSavedArray != nil) {

    [self restoreStateWithData:dataRepresentingSavedArray];

And in -restoreStateWithData:

    NSArray *savedLayers = [NSKeyedUnarchiver unarchiveObjectWithData:data];

if (savedLayers != nil) {

    for(layer in savedLayers) {

        [self.view.layer addSublayer:layer];

    }

    [spaceView.layer layoutSublayers];      
}

2条回答
我想做一个坏孩纸
2楼-- · 2019-07-23 15:40

Just to be precise, according to the Apple docs, the CALayer is actually the model and not the view in the MVC pattern.

"CALayer is the model class for layer-tree objects. It encapsulates the position, size, and transform of a layer, which defines its coordinate system."

The view behind the layer is actually the view part of the pattern. A layer cannot be displayed without a backing view.

It seems to me that it should be a perfectly legitimate candidate for data serialization. Take a look at the KVC Extensions for CALayer. Particularly look at:

- (BOOL)shouldArchiveValueForKey:(NSString *)key
查看更多
乱世女痞
3楼-- · 2019-07-23 15:49

Cocoa (and Cocoa Touch) are mostly based on a model-view-controller organization. CALayers are in the view tier. This leads to two questions:

  1. What part of your model does your layer present to the user?
  2. How do you make that part of the model persist?

The answers to those questions are your solution.

Nowadays, for a new app, the simplest (certainly most extensible) path to a persistent model is probably Core Data.

查看更多
登录 后发表回答