2009-02-20 3 views
2

Я думаю, что, когда я добавляю вид как подвид, как например:CALayer addSublayer увеличивает количество учетных записей?

UIView* view = [[UIView alloc] init]; 
[self addSubview:view]; 
[view release]; 

, что это безопасно выпустить мнение потом ... это то же самое для объекта CALayer? Если я создаю CALayer с помощью/инициализации Alloc, и сделать:

[self.layer addSublayer:layer]; 

это безопасно, чтобы сделать выделение слоя после этого?

ответ

5

Да. В общем случае, если объект A нуждается в объекте B, он несет ответственность за объект A. Поэтому, если «self.layer» нужен «layer», он будет удалять файл keepCount во время addSublayer: и освободить уровень, когда он больше не понадобится. Хотя есть некоторые исключения из этого, эти исключения, как правило, очень хорошо документированы.

+0

Это похоже на случай. У нас есть собственные пользовательские слои, поэтому мы делаем alloc/init, а не layer, но корректировка наших выпусков, похоже, устраняет наши проблемы. :) – Jonas

+0

Исправление: проблема, которую я видел, заключается в том, что если вы «удалите из суперслоя», тогда объект МОЖЕТ быть уничтожен даже внутри одного и того же блока кода. т. е. если вы затем вызовете «layer.sublayers» второй раз, половина элементов в массиве - это ссылки INVALID, которые приведут к краху вашего приложения. AFAICT это неправильно от Apple - этого не должно произойти до тех пор, пока RunLoop не ударит снова. Я просто попал в эту проблему. Мне было бы интересно увидеть ссылки на некоторые «хорошо документированные» случаи - возможно, вам нужна ошибка в документах? :) – Adam

-1

Я согласен с Луи И хотя это на самом деле не нужно в этом случае, обратите внимание, что вы всегда можете использовать метод retainCount: перепроверить эти вещи в будущем, например:..

NSLog(@"Retain count before: %d", [layer retainCount]); 
[self.layer addSublayer:layer]; 
NSLog(@"Retain count after: %d", [layer retainCount]); 
+1

retainCount является печально известным, если не работает. Я догадываюсь, поэтому вы получили downvoted (хотя было бы неплохо, если бы downvoter прокомментировал) – Adam

+0

'keepCount' отлично работает; вам просто нужно помнить, что 'autorelease' не сразу изменяет счет сохранения. Только фактические сообщения 'keep' и' release' уменьшают количество удержаний (и сообщение 'release', соответствующее этому' autorelease', не будут отправляться до тех пор, пока текущий autoreleasepool не будет исчерпан). Это говорит о том, что использование 'keepCount' для чего угодно * кроме того * отладка является ужасным запахом кода. – Quuxplusone

-1

Прежде всего, вам создать новый объект CALayer, используя метод класса класса, а не alloc/init. Например:

CALayer *l = [CALayer layer]; 
l.frame = CGRectMake(...); 
l.position = CGPointMake(...); 
l.anchorpoint = CGPointMake(0,0); 
l.contents = (id)someCGImageRef; 
[self.layer addSublayer:l]; 

Во-вторых, здесь вы можете отклеиваться, потому что если вы освободите CALayer после добавления его в качестве подуровня к основному слою вашего представления, вы получите крах. Или, по крайней мере, я это сделал, и я думаю, что это связано с тем, что метод класса слоя добавляет слой в пул автозапуска, поэтому, если вы его выпустите, вы получите двойной выпуск, и поэтому он будет освобожден, даже если он считает, что основной слой этого вида все еще используется.

Смежные вопросы