how do you copy an CALayer?

2019-01-24 07:00发布

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.)

6条回答
Deceive 欺骗
2楼-- · 2019-01-24 07:09

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

查看更多
冷血范
3楼-- · 2019-01-24 07:13

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

查看更多
贪生不怕死
4楼-- · 2019-01-24 07:18

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.

查看更多
Melony?
6楼-- · 2019-01-24 07:28

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.

查看更多
贪生不怕死
7楼-- · 2019-01-24 07:32

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.

查看更多
登录 后发表回答