Skip to content

Commit

Permalink
Revert "Dispose render objects when owning element is unmounted. (flu…
Browse files Browse the repository at this point in the history
…tter#82883)" (flutter#83790)

This reverts commit c75edc2.
  • Loading branch information
renyou committed Jun 2, 2021
1 parent c75edc2 commit 63c49c3
Show file tree
Hide file tree
Showing 12 changed files with 12 additions and 240 deletions.
2 changes: 2 additions & 0 deletions examples/layers/rendering/src/sector_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
}

class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {

RenderBoxToRenderSectorAdapter({ double innerRadius = 0.0, RenderSector? child })
: _innerRadius = innerRadius {
this.child = child;
Expand Down Expand Up @@ -566,6 +567,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
result.add(BoxHitTestEntry(this, position));
return true;
}

}

class RenderSolidColor extends RenderDecoratedSector {
Expand Down
24 changes: 2 additions & 22 deletions examples/layers/widgets/sectors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,6 @@ class SectorAppState extends State<SectorApp> {
});
}

void recursivelyDisposeChildren(RenderObject parent) {
parent.visitChildren((RenderObject child) {
recursivelyDisposeChildren(child);
child.dispose();
});
}

Widget buildBody() {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expand All @@ -114,12 +107,7 @@ class SectorAppState extends State<SectorApp> {
Container(
padding: const EdgeInsets.all(4.0),
margin: const EdgeInsets.only(right: 10.0),
child: WidgetToRenderBoxAdapter(
renderBox: sectorAddIcon,
onUnmount: () {
recursivelyDisposeChildren(sectorAddIcon);
},
),
child: WidgetToRenderBoxAdapter(renderBox: sectorAddIcon),
),
const Text('ADD SECTOR'),
],
Expand All @@ -134,12 +122,7 @@ class SectorAppState extends State<SectorApp> {
Container(
padding: const EdgeInsets.all(4.0),
margin: const EdgeInsets.only(right: 10.0),
child: WidgetToRenderBoxAdapter(
renderBox: sectorRemoveIcon,
onUnmount: () {
recursivelyDisposeChildren(sectorRemoveIcon);
},
),
child: WidgetToRenderBoxAdapter(renderBox: sectorRemoveIcon),
),
const Text('REMOVE SECTOR'),
],
Expand All @@ -159,9 +142,6 @@ class SectorAppState extends State<SectorApp> {
child: WidgetToRenderBoxAdapter(
renderBox: sectors,
onBuild: doUpdates,
onUnmount: () {
recursivelyDisposeChildren(sectors);
},
),
),
),
Expand Down
9 changes: 0 additions & 9 deletions packages/flutter/lib/src/rendering/editable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,6 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
_RenderEditableCustomPaint? _foregroundRenderObject;
_RenderEditableCustomPaint? _backgroundRenderObject;

@override
void dispose() {
_foregroundRenderObject?.dispose();
_foregroundRenderObject = null;
_backgroundRenderObject?.dispose();
_backgroundRenderObject = null;
super.dispose();
}

void _updateForegroundPainter(RenderEditablePainter? newPainter) {
final _CompositeRenderEditablePainter effectivePainter = newPainter == null
? _builtInForegroundPainters
Expand Down
7 changes: 0 additions & 7 deletions packages/flutter/lib/src/rendering/image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -438,13 +438,6 @@ class RenderImage extends RenderBox {
);
}

@override
void dispose() {
_image?.dispose();
_image = null;
super.dispose();
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
Expand Down
75 changes: 0 additions & 75 deletions packages/flutter/lib/src/rendering/object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1111,19 +1111,6 @@ class PipelineOwner {
/// The [RenderBox] subclass introduces the opinion that the layout
/// system uses Cartesian coordinates.
///
/// ## Lifecycle
///
/// A [RenderObject] must [dispose] when it is no longer needed. The creator
/// of the object is responsible for disposing of it. Typically, the creator is
/// a [RenderObjectElement], and that element will dispose the object it creates
/// when it is unmounted.
///
/// [RenderObject]s are responsible for cleaning up any expensive resources
/// they hold when [dispose] is called, such as [Picture] or [Image] objects.
/// This includes any [Layer]s that the render object has directly created. The
/// base implementation of dispose will nullify the [layer] property. Subclasses
/// must also nullify any other layer(s) it directly creates.
///
/// ## Writing a RenderObject subclass
///
/// In most cases, subclassing [RenderObject] itself is overkill, and
Expand Down Expand Up @@ -1243,50 +1230,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
});
}

/// Whether this has been disposed.
///
/// If asserts are disabled, this property is always null.
bool? get debugDisposed {
bool? disposed;
assert(() {
disposed = _debugDisposed;
return true;
}());
return disposed;
}

bool _debugDisposed = false;

/// Release any resources held by this render object.
///
/// The object that creates a RenderObject is in charge of disposing it.
/// If this render object has created any children directly, it must dispose
/// of those children in this method as well. It must not dispose of any
/// children that were created by some other object, such as
/// a [RenderObjectElement]. Those children will be disposed when that
/// element unmounts, which may be delayed if the element is moved to another
/// part of the tree.
///
/// Implementations of this method must end with a call to the inherited
/// method, as in `super.dispose()`.
///
/// The object is no longer usable after calling dispose.
@mustCallSuper
void dispose() {
assert(!_debugDisposed);
_layer = null;
assert(() {
visitChildren((RenderObject child) {
assert(
child.debugDisposed!,
'${child.runtimeType} (child of $runtimeType) must be disposed before calling super.dispose().',
);
});
_debugDisposed = true;
return true;
}());
}

// LAYOUT

/// Data for use by the parent render object.
Expand Down Expand Up @@ -1424,10 +1367,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
bool get _debugCanPerformMutations {
late bool result;
assert(() {
if (_debugDisposed) {
result = false;
return true;
}
if (owner != null && !owner!.debugDoingLayout) {
result = true;
return true;
Expand Down Expand Up @@ -1462,7 +1401,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im

@override
void attach(PipelineOwner owner) {
assert(!_debugDisposed);
super.attach(owner);
// If the node was dirtied in some way while unattached, make sure to add
// it to the appropriate dirty list now that an owner is available
Expand Down Expand Up @@ -1674,7 +1612,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
///
/// See [RenderView] for an example of how this function is used.
void scheduleInitialLayout() {
assert(!_debugDisposed);
assert(attached);
assert(parent is! RenderObject);
assert(!owner!._debugDoingLayout);
Expand Down Expand Up @@ -1744,7 +1681,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// work to update its layout information.
@pragma('vm:notify-debugger-on-exception')
void layout(Constraints constraints, { bool parentUsesSize = false }) {
assert(!_debugDisposed);
if (!kReleaseMode && debugProfileLayoutsEnabled)
Timeline.startSync('$runtimeType', arguments: timelineArgumentsIndicatingLandmarkEvent);

Expand Down Expand Up @@ -2104,7 +2040,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// it cannot be the case that _only_ the compositing bits changed,
/// something else will have scheduled a frame for us.
void markNeedsCompositingBitsUpdate() {
assert(!_debugDisposed);
if (_needsCompositingBitsUpdate)
return;
_needsCompositingBitsUpdate = true;
Expand Down Expand Up @@ -2203,7 +2138,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// layer, thus limiting the number of nodes that [markNeedsPaint] must mark
/// dirty.
void markNeedsPaint() {
assert(!_debugDisposed);
assert(owner == null || !owner!.debugDoingPaint);
if (_needsPaint)
return;
Expand Down Expand Up @@ -2288,7 +2222,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
///
/// This might be called if, e.g., the device pixel ratio changed.
void replaceRootLayer(OffsetLayer rootLayer) {
assert(!_debugDisposed);
assert(rootLayer.attached);
assert(attached);
assert(parent is! RenderObject);
Expand All @@ -2301,7 +2234,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
}

void _paintWithContext(PaintingContext context, Offset offset) {
assert(!_debugDisposed);
assert(() {
if (_debugDoingThisPaint) {
throw FlutterError.fromParts(<DiagnosticsNode>[
Expand Down Expand Up @@ -2525,7 +2457,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
///
/// See [RendererBinding] for an example of how this function is used.
void scheduleInitialSemantics() {
assert(!_debugDisposed);
assert(attached);
assert(parent is! RenderObject);
assert(!owner!._debugDoingSemantics);
Expand Down Expand Up @@ -2648,7 +2579,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// [RenderObject] as annotated by [describeSemanticsConfiguration] changes in
/// any way to update the semantics tree.
void markNeedsSemanticsUpdate() {
assert(!_debugDisposed);
assert(!attached || !owner!._debugDoingSemantics);
if (!attached || owner!._semanticsOwner == null) {
_cachedSemanticsConfiguration = null;
Expand Down Expand Up @@ -2894,10 +2824,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
@override
String toStringShort() {
String header = describeIdentity(this);
if (_debugDisposed) {
header += ' DISPOSED';
return header;
}
if (_relayoutBoundary != null && _relayoutBoundary != this) {
int count = 1;
RenderObject? target = parent as RenderObject?;
Expand Down Expand Up @@ -3283,7 +3209,6 @@ mixin ContainerRenderObjectMixin<ChildType extends RenderObject, ParentDataType
}
}
}

/// Insert child into this render object's child list after the given child.
///
/// If `after` is null, then this inserts the child at the start of the list,
Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/src/rendering/proxy_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3152,6 +3152,7 @@ class RenderRepaintBoundary extends RenderProxyBox {
return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
}


/// The number of times that this render object repainted at the same time as
/// its parent. Repaint boundaries are only useful when the parent and child
/// paint at different times. When both paint at the same time, the repaint
Expand Down
34 changes: 0 additions & 34 deletions packages/flutter/lib/src/widgets/basic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6232,19 +6232,13 @@ class DefaultAssetBundle extends InheritedWidget {
/// A given render object can be placed at most once in the widget tree. This
/// widget enforces that restriction by keying itself using a [GlobalObjectKey]
/// for the given render object.
///
/// This widget will call [RenderObject.dispose] on the [renderBox] when it is
/// unmounted. After that point, the [renderBox] will be unusable. If any
/// children have been added to the [renderBox], they must be disposed in the
/// [onUnmount] callback.
class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
/// Creates an adapter for placing a specific [RenderBox] in the widget tree.
///
/// The [renderBox] argument must not be null.
WidgetToRenderBoxAdapter({
required this.renderBox,
this.onBuild,
this.onUnmount,
}) : assert(renderBox != null),
// WidgetToRenderBoxAdapter objects are keyed to their render box. This
// prevents the widget being used in the widget hierarchy in two different
Expand All @@ -6253,9 +6247,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
super(key: GlobalObjectKey(renderBox));

/// The render box to place in the widget tree.
///
/// This widget takes ownership of the render object. When it is unmounted,
/// it also calls [RenderObject.dispose].
final RenderBox renderBox;

/// Called when it is safe to update the render box and its descendants. If
Expand All @@ -6264,38 +6255,13 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
/// tree will be dirty.
final VoidCallback? onBuild;

/// Called when it is safe to dispose of children that were manually added to
/// the [renderBox].
///
/// Do not dispose the [renderBox] itself, as it will be disposed by the
/// framework automatically. However, during that process the framework will
/// check that all children of the [renderBox] have also been disposed.
/// Typically, child [RenderObject]s are disposed by corresponding [Element]s
/// when they are unmounted. However, child render objects that were manually
/// added do not have corresponding [Element]s to manage their lifecycle, and
/// need to be manually disposed here.
///
/// See also:
///
/// * [RenderObjectElement.unmount], which invokes this callback before
/// disposing of its render object.
/// * [RenderObject.dispose], which instructs a render object to release
/// any resources it may be holding.
final VoidCallback? onUnmount;

@override
RenderBox createRenderObject(BuildContext context) => renderBox;

@override
void updateRenderObject(BuildContext context, RenderBox renderObject) {
onBuild?.call();
}

@override
void didUnmountRenderObject(RenderObject renderObject) {
assert(renderObject == renderBox);
onUnmount?.call();
}
}


Expand Down
Loading

0 comments on commit 63c49c3

Please sign in to comment.