你如何复制CALayer?

时间:2009-03-29 16:28:05

标签: iphone objective-c core-animation calayer

如何让NSArray充满CALayer的多个实例(所有实例都具有相同的框架,内容等)?

背景:CALayer需要一些开销来创建,所以我想在类的init方法中创建一些CALayers(都共享相同的属性)(稍后将在该类中使用。)< / p>

7 个答案:

答案 0 :(得分:22)

我没有专门针对CALayer尝试此操作,但我知道您可以利用NSCoding执行深层复制:

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

我不确定如何复制它们对性能有什么帮助。

答案 1 :(得分:5)

CALayer没有内置的-(id)copy方法。我不知道为什么。然而,为你自己搞砸并不难。创建CALayer类别并编写自己的复制方法。您所要做的就是实例化并手动从原件获取公共ivars / properties并设置为新副本。别忘了拨打[super copy]

BTW,CALayer是一个对象。您可以将其添加到NSArray。

答案 2 :(得分:1)

我在程序中做了同样的事情。

在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];

基本上,我只是反复创建CALayer对象。它比复制它们更快,因为这种方法每个属性只需要1个CALayer调用,而不是复制它需要你读取属性然后另外设置它。我在大约0.02秒内使用这种方法产生大约500个物体,所以它肯定很快。如果你真的需要更快的速度,你甚至可以缓存图像文件。

答案 3 :(得分:1)

答案 4 :(得分:0)

因此使用NSProxy。您所描述的是一种常见的场景,并且可以从中导出任意数量的设计模式。

Pro的Objective-C设计模式为您描述的问题提供了解决方案;阅读第3章:原型模式。这是一个摘要定义:

Prototype模式指定使用原型实例创建的对象类型,通过复制此实例创建新对象

答案 5 :(得分:0)

有可能以CALayerReplicator的方式,我提供更多细节in response to this other similar question

答案 6 :(得分:0)

MaxGabriel 评分最高的答案的更新链接。

目标-C

CALayer *layer1;
CALayer *layer2;

// Set up layer1's specifics.

layer2 = [NSKeyedUnarchiver unarchivedObjectOfClass:[CALayer class]
                                                            fromData:[NSKeyedArchiver archivedDataWithRootObject:layer1 requiringSecureCoding:NO error:nil] error:nil];

在 Swift 中。

let layer1: CALayer?
var layer2: CALayer? = nil
// Set up layer1's specifics

do {
    layer2 = try NSKeyedUnarchiver.unarchivedObject(
        ofClass: CALayer.self,
        from: try NSKeyedArchiver.archivedData(withRootObject: layer1, requiringSecureCoding: false))
} catch {
// It failed.  Do something. 
}
相关问题