flutter_in_action_2nd icon indicating copy to clipboard operation
flutter_in_action_2nd copied to clipboard

通过 Layer 实现绘制缓存 有点小问题

Open zmtzawqlp opened this issue 2 years ago • 0 comments

14.7.1 通过 Layer 实现绘制缓存

https://book.flutterchina.club/chapter14/layer.html#_14-7-1-%E9%80%9A%E8%BF%87-layer-%E5%AE%9E%E7%8E%B0%E7%BB%98%E5%88%B6%E7%BC%93%E5%AD%98

这一章中,直接利用 Layer 缓存是有问题的。child 默认的 _parentHandle 会在 removeAllChildren 方法中, dispose 掉它。下次绘制直接使用就会报错。

void removeAllChildren() {
  Layer? child = firstChild;
  while (child != null) {
    final Layer? next = child.nextSibling;
    child._previousSibling = null;
    child._nextSibling = null;
    assert(child.attached == attached);
    dropChild(child);
    assert(child._parentHandle != null);
    child._parentHandle.layer = null;
    child = next;
  }
  _firstChild = null;
  _lastChild = null;
}
@override
 void dispose() {
   picture = null; // Will dispose _picture.
   super.dispose();
 }

再为它 配置一个 LayerHandle 的话,_refCount 就等于 2了,这样才能避免 _parentHandle 去提前释放它。

  set layer(T? layer) {
    assert(
      layer?.debugDisposed != true,
      'Attempted to create a handle to an already disposed layer: $layer.',
    );
    if (identical(layer, _layer)) {
      return;
    }
    _layer?._unref();
    _layer = layer;
    if (_layer != null) {
      _layer!._refCount += 1;
    }
  }

Layer 的 _unref 方法

  void _unref() {
    assert(_refCount > 0);
    _refCount -= 1;
    if (_refCount == 0) {
      dispose();
    }
  }

zmtzawqlp avatar May 31 '23 09:05 zmtzawqlp