Skip to content

Commit e59b839

Browse files
authored
Merge branch 'release/8.14' into alwx/backport/8.14-craft-disttag
2 parents 6ee3bd6 + df557e5 commit e59b839

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
77
<!-- prettier-ignore-end -->
88
9+
## 8.14.2
10+
11+
### Fixes
12+
13+
- Fix iOS retain cycle in `RNSentryOnDrawReporterView` leaking TTID/TTFD reporter views and their frame-tracker listeners ([#6449](https://github.com/getsentry/sentry-react-native/pull/6449))
14+
915
## 8.14.1
1016

1117
### Fixes

packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryOnDrawReporterTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,22 @@ final class RNSentryOnDrawReporterTests: XCTestCase {
145145

146146
emitNewFrameCallback!(1)
147147
}
148+
149+
func testReporterViewIsDeallocatedAfterRelease() {
150+
// Guards against the retain cycle described in
151+
// https://github.com/getsentry/sentry-react-native/issues/6440 where the
152+
// emit-new-frame block captured `self` strongly, keeping the view (and
153+
// its frames-tracker listener) alive forever.
154+
weak var weakReporter: RNSentryOnDrawReporterView?
155+
156+
autoreleasepool {
157+
let reporter = RNSentryOnDrawReporterView.createWithMockedListener()
158+
reporter!.initialDisplay = true
159+
reporter!.parentSpanId = spanId
160+
reporter!.didSetProps(["initialDisplay", "parentSpanId"])
161+
weakReporter = reporter
162+
}
163+
164+
XCTAssertNil(weakReporter, "RNSentryOnDrawReporterView leaked due to a retain cycle")
165+
}
148166
}

packages/core/ios/RNSentryOnDrawReporter.m

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,29 @@ - (instancetype)init
4040

4141
- (RNSentryEmitNewFrameEvent)createEmitNewFrameEvent
4242
{
43+
__weak __typeof__(self) weakSelf = self;
4344
return ^(NSNumber *newFrameTimestampInSeconds) {
44-
self->isListening = NO;
45+
__strong __typeof__(weakSelf) strongSelf = weakSelf;
46+
if (strongSelf == nil) {
47+
return;
48+
}
49+
50+
strongSelf->isListening = NO;
4551

46-
if (![_parentSpanId isKindOfClass:[NSString class]]) {
52+
if (![strongSelf->_parentSpanId isKindOfClass:[NSString class]]) {
4753
return;
4854
}
4955

50-
if (self->_fullDisplay) {
56+
if (strongSelf->_fullDisplay) {
5157
[RNSentryTimeToDisplay
52-
putTimeToDisplayFor:[@"ttfd-" stringByAppendingString:self->_parentSpanId]
58+
putTimeToDisplayFor:[@"ttfd-" stringByAppendingString:strongSelf->_parentSpanId]
5359
value:newFrameTimestampInSeconds];
5460
return;
5561
}
5662

57-
if (self->_initialDisplay) {
63+
if (strongSelf->_initialDisplay) {
5864
[RNSentryTimeToDisplay
59-
putTimeToDisplayFor:[@"ttid-" stringByAppendingString:self->_parentSpanId]
65+
putTimeToDisplayFor:[@"ttid-" stringByAppendingString:strongSelf->_parentSpanId]
6066
value:newFrameTimestampInSeconds];
6167
return;
6268
}

0 commit comments

Comments
 (0)