Подложка UIView - делегат зомби - PullRequest
0 голосов
/ 05 апреля 2011

У меня есть класс UIView, который использует собственный слой поддержки, полученный из CALayer. у меня есть статический метод layerClass, который возвращает класс моего пользовательского класса CALayer.

+ (Class)layerClass
{
    return [CellLayer class];
}

Внутри этого класса (CellLayer) я приведу делегат к классу UIView, который содержит слой поддержки - в частности, в методе drawInContext: я делаю это:

CellClass* cell = (CellClass*)self.delegate;

(где CellCass является подклассом UIView)

Это работает нормально, за исключением того, что иногда вызывается метод drawInContext:, а делегатом является зомби (NSZombieEnabled имеет значение TRUE).

Похоже, что происходит то, что, когда объект ячейки удаляется из его суперпредставления (который является UIScrollView), ячейка освобождается до того, как освобождается слой поддержки, и слой поддержки получает вызов drawInContext:. Заявления NSLog показывают, что ОБА методы-деэллоки в конечном итоге вызываются (т. Е. Вызываются оба варианта: UIView и CALayer), но я не могу точно сказать, в каком порядке, поскольку приложение, использующее это, имеет десятки и десятки этих ячеек - я думаю, я мог бы измените NSLog так, чтобы он отображал адрес ячейки в консоли, и сопоставьте разлочку UIView и разлочку CALayer, но я не потрудился сделать это.

Я ожидал, что резервный слой будет выпущен до UIView, который содержит его.

Это правильное поведение? Мой текущий обходной путь заключается в том, что в dealloc UIView я установил флаг на заднем слое (viewWasReleased), а в drawInContext просто возвращаю, если этот флаг установлен.

Есть ли лучший, более чистый способ сделать это?

1 Ответ

0 голосов
/ 04 мая 2011

сегодня у меня возник тот же вопрос, и я наконец-то исправил свою проблему.

Проблема заключалась в том, что при вызове метода dealloc ваш CellLayer не уничтожается, поскольку он имеет ссылку на текущий объект.(делегат) Таким образом, CALayer не уничтожается, а self.delegate является освобожденным экземпляром.The zombie one.

Я исправил это добавление в моем классе метода viewDidDisappear, и там я добавил следующий код:

if(cell != nil)
    cell.delegate = nil;

Затем, когда метод dealloc вызывается в моем объекте, естьв CALayer нет ссылки на него, так что просто self.cell = nil;Объект CALayer будет уничтожен раньше, и у вас не будет проблем с делегатом.

...