-
Notifications
You must be signed in to change notification settings - Fork 6k
iOS: Eliminate FlutterEngine dealloc notification #56650
Conversation
| // That's reasonable behaviour on a regular NSPointerArray but not for a weakObjectPointerArray. | ||
| // As a workaround, we mutate it first. See: http://www.openradar.me/15396578 | ||
| [self.engines addPointer:nil]; | ||
| [self.engines compact]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't comment on just how much time I spent staring at and debugging this line to arrive at the comment above. Thanks, noble OpenRadar submitter, for saving my sanity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😭
| XCTAssertNotNil(spawner); | ||
| XCTAssertNotNil(weakSpawner); | ||
| } | ||
| XCTAssertNil(weakSpawner); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could probably get rid of this additional check, but it's arguably useful for avoiding any future accidents wherein someone updates the implementation to hold a strong reference that retains the engine instead of a weak reference. :/
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
shell/platform/darwin/ios/framework/Source/FlutterEngineGroup.mm
Outdated
Show resolved
Hide resolved
FlutterEngineGroup keeps an array of all live FlutterEngine instances it has created such that after the first engine, it can spawn further engines using the first. Previously we manually managed this array by adding engines to it upon creation, then having [FlutterEngine dealloc] emit a notification such that FlutterEngineGroup can listen for it, and remove instances from the array upon dealloc. Instead, we now use an NSPointerArray of of weak pointers such that pointers are automatically nilled out by ARC after the last strong reference is collected. This eliminates the need for the manual notification during dealloc. Unfortunately, NSPointerArray is "clever" and assumes that if the array has not been mutated to store a nil pointer since its last compact call, it must must contain a nil pointer and can thus skip compaction. When holding weak pointers under ARC, this is no longer the case and so we work around the issue by storing a nil pointer before calling compact. See: http://www.openradar.me/15396578 I'm not thrilled with the fact that we're replacing one sort of TODO with another, but the code is much simpler and avoids relying on a trip through the notification center, which seems objectively better. Issue: flutter/flutter#155943
…159047) flutter/engine@6f9854a...9d0720a 2024-11-17 skia-flutter-autoroll@skia.org Roll Skia from b88c7b03a838 to 1086e39c04cf (1 revision) (flutter/engine#56654) 2024-11-17 chris@bracken.jp iOS: Eliminate FlutterEngine dealloc notification (flutter/engine#56650) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jimgraham@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
FlutterEngineGroup keeps an array of all live FlutterEngine instances it has created such that after the first engine, it can spawn further engines using the first. Previously we manually managed this array by adding engines to it upon creation, then having [FlutterEngine dealloc] emit a notification such that FlutterEngineGroup can listen for it, and remove instances from the array upon reception of the notification. Instead, we now use an NSPointerArray of of weak pointers such that pointers are automatically nilled out by ARC after the last strong reference is collected. This eliminates the need for the manual notification during dealloc. Unfortunately, NSPointerArray is "clever" and assumes that if the array has not been mutated to store a nil pointer since its last compact call, it must not contain a nil pointer and can thus skip compaction. Under ARC, weak pointers are automatically nilled out when the last strong reference is released, so the above heuristic is no longer valid. We work around the issue by storing a nil pointer before calling compact. See http://www.openradar.me/15396578 for the radar tracking this bug. I'm not thrilled with the fact that we're replacing one sort of TODO with another, but the code is much simpler and avoids relying on a trip through the notification center, which seems objectively better. Issue: flutter#155943 Issue: flutter#137801 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
FlutterEngineGroup keeps an array of all live FlutterEngine instances it has created such that after the first engine, it can spawn further engines using the first.
Previously we manually managed this array by adding engines to it upon creation, then having [FlutterEngine dealloc] emit a notification such that FlutterEngineGroup can listen for it, and remove instances from the array upon reception of the notification.
Instead, we now use an NSPointerArray of of weak pointers such that pointers are automatically nilled out by ARC after the last strong reference is collected. This eliminates the need for the manual notification during dealloc.
Unfortunately, NSPointerArray is "clever" and assumes that if the array has not been mutated to store a nil pointer since its last compact call, it must not contain a nil pointer and can thus skip compaction. Under ARC, weak pointers are automatically nilled out when the last strong reference is released, so the above heuristic is no longer valid. We work around the issue by storing a nil pointer before calling compact.
See http://www.openradar.me/15396578 for the radar tracking this bug.
I'm not thrilled with the fact that we're replacing one sort of TODO with another, but the code is much simpler and avoids relying on a trip through the notification center, which seems objectively better.
Issue: flutter/flutter#155943
Issue: flutter/flutter#137801
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.