File tree Expand file tree Collapse file tree
engine/src/flutter/shell/platform/darwin/ios/framework/Source Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -58,7 +58,8 @@ public class VSyncClient: NSObject {
5858
5959 super. init ( )
6060
61- let link = CADisplayLink ( target: self , selector: #selector( onDisplayLink ( _: ) ) )
61+ let relay = DisplayLinkRelay ( target: self )
62+ let link = CADisplayLink ( target: relay, selector: #selector( DisplayLinkRelay . onDisplayLink ( _: ) ) )
6263 link. isPaused = true
6364 self . displayLink = link
6465
@@ -186,3 +187,21 @@ public class VSyncClient: NSObject {
186187 callback ( timestamp, targetTimestamp)
187188 }
188189}
190+
191+ /// A weak proxy target for `CADisplayLink` callbacks to prevent retain cycles.
192+ ///
193+ /// `CADisplayLink` strongly retains its target. If the display link directly targeted `VSyncClient`,
194+ /// it would form a strong retain cycle (since `VSyncClient` also strongly retains the `CADisplayLink`
195+ /// instance). Instead, we route display link callbacks through this intermediate relay holding `VSyncClient` weakly.
196+ private final class DisplayLinkRelay : NSObject {
197+ private weak var target : VSyncClient ?
198+
199+ init ( target: VSyncClient ) {
200+ self . target = target
201+ }
202+
203+ @objc
204+ func onDisplayLink( _ link: CADisplayLink ) {
205+ target? . onDisplayLink ( link)
206+ }
207+ }
Original file line number Diff line number Diff line change @@ -197,4 +197,20 @@ class VSyncClientTest: XCTestCase {
197197 waitForExpectations ( timeout: 1.0 , handler: nil )
198198 XCTAssertNil ( weakClient)
199199 }
200+
201+ func testDeallocatesWithoutExplicitInvalidation( ) {
202+ let threadTaskRunner = TaskRunnerTestHelper . makeTaskRunner ( withLabel: " VSyncClientTest " )
203+ weak var weakClient : VSyncClient ?
204+
205+ autoreleasepool {
206+ let client = VSyncClient (
207+ taskRunner: threadTaskRunner,
208+ isVariableRefreshRateEnabled: false ,
209+ maxRefreshRate: 60.0
210+ ) { _, _ in }
211+ weakClient = client
212+ }
213+
214+ XCTAssertNil ( weakClient)
215+ }
200216}
You can’t perform that action at this time.
0 commit comments