как вы копируете CALayer? - PullRequest
       15

как вы копируете CALayer?

10 голосов
/ 29 марта 2009

Как сделать NSArray полным из нескольких экземпляров CALayer (все с одинаковым фреймом, содержимым и т. Д.)?

Справочная информация: для создания CALayer требуется немного ресурсов, поэтому я хотел бы создать несколько CALayers (все с одинаковыми свойствами) в методе init класса (который будет использоваться позже в этом классе.)

Ответы [ 6 ]

22 голосов
/ 12 декабря 2012

Я не пробовал это специально с CALayer, но я знаю, что вы можете выполнить глубокое копирование, воспользовавшись NSCoding:

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

Я не уверен, как их копирование действительно поможет с производительностью.

5 голосов
/ 30 марта 2009

CALayer не имеет встроенного метода -(id)copy. Я не уверен почему. Тем не менее, нетрудно создать свой собственный. Создайте категорию CALayer и напишите свой собственный метод копирования. Все, что вам нужно сделать, это создать экземпляр и вручную получить общедоступные ivars / properties из оригинала и установить новую копию. Не забудьте позвонить [super copy]

Кстати, CALayer - это объект. Вы можете добавить его в NSArray.

1 голос
/ 02 марта 2015

Попробуйте использовать CAReplicatorLayer, он может дублировать ваши слои.

ссылка: https://developer.apple.com/documentation/quartzcore/careplicatorlayer

пример кода: http://www.knowstack.com/swift-careplicatorlayer-sample-code/ https://developer.apple.com/documentation/quartzcore/careplicatorlayer/1522391-instancedelay

1 голос
/ 31 мая 2010

Я делаю то же самое в моей программе.

В 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 для свойства, а не для его копирования, который требует, чтобы вы прочитали свойство и затем дополнительно установили его. Я породил около 500 объектов, используя этот метод за 0,02 секунды, так что это определенно быстро. Если вам действительно нужно больше скорости, вы можете даже кэшировать файл изображения.

0 голосов
/ 26 апреля 2018

Это возможно каким-то образом с CALayerReplicator, я даю более подробную информацию в ответ на этот другой похожий вопрос

0 голосов
/ 22 ноября 2016

NSProxy используется по этой причине. То, что вы описываете, является распространенным сценарием, из которого происходит любое количество шаблонов проектирования.

Pro Objective-C Design Patterns для iOS обеспечивает решение самой проблемы, которую вы описываете; прочитайте главу 3: Образец прототипа. Вот краткое определение:

Шаблон Prototype указывает тип объектов, создаваемых с использованием экземпляра-прототипа, в результате чего создается новый объект путем копирования этого экземпляра

...