how do you copy an CALayer?

2019-01-24 07:13发布

问题:

How to you make an NSArray full of multiple instances of a CALayer (all with the same frame, contents etc)?

Background: CALayer takes a bit of overhead to create, so I would like to create a number of CALayers (all sharing the same properties) in the init method of a class (to be used later on in that class.)

回答1:

CALayer doesn't have a built in -(id)copy method. I'm not sure why. It's not difficult to gin up your own however. Create a CALayer category and write your own copy method. All you have to do is instantiate and manually get the public ivars/properties from the original and set to the new copy. Don't forget to call [super copy]

BTW, CALayer is an object. You can add it to an NSArray.



回答2:

I haven't tried this with CALayer specifically, but I know you can perform a deep-copy by taking advantage of NSCoding:

CALayer *layer = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:layer]];

I'm not sure how copying them would really help with performance, though.



回答3:

I do exactly the same thing in my program.

In init:

    self.turrets = [NSMutableArray array];
    for (count = 0; count < kMaxTurrets; count++)
        [self spawnTurret];

spawnTurret:

evTurret* aTurret = [[[evTurret alloc] init] autorelease];
CGImageRef theImage = [self turretContents];
aTurret.contents = theImage;
double imageHeight = CGImageGetHeight(theImage);
double imageWidth = CGImageGetWidth(theImage);
double turretSize = 0.06*(mapLayer.bounds.size.width + mapLayer.bounds.size.height)/2.0;
aTurret.bounds = CGRectMake(-turretSize*0.5, turretSize*0.5, turretSize*(imageWidth/imageHeight), turretSize);
aTurret.hidden = YES;
[mapLayer addSublayer:aTurret]; 
[self.turrets addObject:aTurret];

Basically, just I just repeatedly create CALayer objects. It's going to be faster than copying them, as this method only requires 1 CALayer call per property, as opposed to copying it which requires you to read the property and then additionally set it. I spawn about 500 objects using this method in about 0.02 seconds, so it's definitely fast. If you really needed more speed you could even cache the image file.



回答4:

Try to use CAReplicatorLayer it can duplicate your layers.

reference: https://developer.apple.com/documentation/quartzcore/careplicatorlayer

sample code: http://www.knowstack.com/swift-careplicatorlayer-sample-code/ https://developer.apple.com/documentation/quartzcore/careplicatorlayer/1522391-instancedelay



回答5:

NSProxy is used for that reason. What you're describing is a common scenario, and one from which any number of design patterns are derived.

Pro Objective-C Design Patterns for iOS provides the solution to the very problem you describe; read Chapter 3: The Protoype Pattern. Here's a summary definition:

The Prototype pattern specifies the kind of objects to create using a prototypical instance, whereby a new object is created by copying this instan



回答6:

It's possible in a way with CALayerReplicator, I give some more details in response to this other similar question