how do you copy an CALayer?
-
22-08-2019 - |
Question
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.)
Solution
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.
OTHER TIPS
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.
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.
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
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
It's possible in a way with CALayerReplicator, I give some more details in response to this other similar question