Skip to content

Commit

Permalink
iOS: Fix Animated image crash when CADisplayLink target in RCTWeakPro…
Browse files Browse the repository at this point in the history
…xy is nil

Summary:
## Problem
When self is nil, this may crash in RCTUIImageViewAnimated.m.

```
_displayLink = [CADisplayLink displayLinkWithTarget:[RCTWeakProxy weakProxyWithTarget:self] selector:selector(displayDidRefresh:)];
```

## Fix

Replace `RCTWeakProxy` with a concrete class `RCTDisplayWeakRefreshable` that has the displayDidRefresh method, that calls the displayDidRefresh method in its weak target.

### Original Github Issue
#28070 (comment)

Changelog: [iOS] [Fixed] -  Fix Animated image crash when CADisplayLink target in RCTWeakProxy is nil

Reviewed By: shergin

Differential Revision: D21419385

fbshipit-source-id: da7c3c38f81ea54f633da7f59359e07680ea2faf
  • Loading branch information
p-sun authored and facebook-github-bot committed May 13, 2020
1 parent 649e1b7 commit e5a6655
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 36 deletions.
22 changes: 22 additions & 0 deletions Libraries/Image/RCTDisplayWeakRefreshable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <Foundation/Foundation.h>

@protocol RCTDisplayRefreshable

- (void)displayDidRefresh:(CADisplayLink *)displayLink;

@end

@interface RCTDisplayWeakRefreshable : NSObject

@property (nonatomic, weak) id<RCTDisplayRefreshable> refreshable;

+ (CADisplayLink *)displayLinkWithWeakRefreshable:(id<RCTDisplayRefreshable>)refreshable;

@end
29 changes: 29 additions & 0 deletions Libraries/Image/RCTDisplayWeakRefreshable.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "RCTDisplayWeakRefreshable.h"

@implementation RCTDisplayWeakRefreshable

+ (CADisplayLink *)displayLinkWithWeakRefreshable:(id<RCTDisplayRefreshable>)refreshable {
RCTDisplayWeakRefreshable *target = [[RCTDisplayWeakRefreshable alloc] initWithRefreshable:refreshable];
return [CADisplayLink displayLinkWithTarget:target selector:@selector(displayDidRefresh:)];
}

- (instancetype)initWithRefreshable:(id<RCTDisplayRefreshable>)refreshable
{
if (self = [super init]) {
_refreshable = refreshable;
}
return self;
}

- (void)displayDidRefresh:(CADisplayLink *)displayLink {
[_refreshable displayDidRefresh:displayLink];
}

@end
6 changes: 3 additions & 3 deletions Libraries/Image/RCTUIImageViewAnimated.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

#import <React/RCTUIImageViewAnimated.h>
#import <React/RCTWeakProxy.h>
#import <React/RCTDisplayWeakRefreshable.h>

#import <mach/mach.h>
#import <objc/runtime.h>
Expand All @@ -29,7 +29,7 @@ static NSUInteger RCTDeviceFreeMemory() {
return (vm_stat.free_count - vm_stat.speculative_count) * page_size;
}

@interface RCTUIImageViewAnimated () <CALayerDelegate>
@interface RCTUIImageViewAnimated () <CALayerDelegate, RCTDisplayRefreshable>

@property (nonatomic, assign) NSUInteger maxBufferSize;
@property (nonatomic, strong, readwrite) UIImage *currentFrame;
Expand Down Expand Up @@ -153,7 +153,7 @@ - (CADisplayLink *)displayLink
}

if (!_displayLink) {
_displayLink = [CADisplayLink displayLinkWithTarget:[RCTWeakProxy weakProxyWithTarget:self] selector:@selector(displayDidRefresh:)];
_displayLink = [RCTDisplayWeakRefreshable displayLinkWithWeakRefreshable:self];
NSString *runLoopMode = [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode];
}
Expand Down
66 changes: 33 additions & 33 deletions RNTester/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PODS:
- React-Core (= 1000.0.0)
- React-jsi (= 1000.0.0)
- ReactCommon/turbomodule/core (= 1000.0.0)
- Flipper (0.37.0):
- Flipper (0.41.5):
- Flipper-Folly (~> 2.2)
- Flipper-RSocket (~> 1.1)
- Flipper-DoubleConversion (1.1.7)
Expand All @@ -25,36 +25,36 @@ PODS:
- Flipper-PeerTalk (0.0.4)
- Flipper-RSocket (1.1.0):
- Flipper-Folly (~> 2.2)
- FlipperKit (0.37.0):
- FlipperKit/Core (= 0.37.0)
- FlipperKit/Core (0.37.0):
- Flipper (~> 0.37.0)
- FlipperKit (0.41.5):
- FlipperKit/Core (= 0.41.5)
- FlipperKit/Core (0.41.5):
- Flipper (~> 0.41.5)
- FlipperKit/CppBridge
- FlipperKit/FBCxxFollyDynamicConvert
- FlipperKit/FBDefines
- FlipperKit/FKPortForwarding
- FlipperKit/CppBridge (0.37.0):
- Flipper (~> 0.37.0)
- FlipperKit/FBCxxFollyDynamicConvert (0.37.0):
- FlipperKit/CppBridge (0.41.5):
- Flipper (~> 0.41.5)
- FlipperKit/FBCxxFollyDynamicConvert (0.41.5):
- Flipper-Folly (~> 2.2)
- FlipperKit/FBDefines (0.37.0)
- FlipperKit/FKPortForwarding (0.37.0):
- FlipperKit/FBDefines (0.41.5)
- FlipperKit/FKPortForwarding (0.41.5):
- CocoaAsyncSocket (~> 7.6)
- Flipper-PeerTalk (~> 0.0.4)
- FlipperKit/FlipperKitHighlightOverlay (0.37.0)
- FlipperKit/FlipperKitLayoutPlugin (0.37.0):
- FlipperKit/FlipperKitHighlightOverlay (0.41.5)
- FlipperKit/FlipperKitLayoutPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutTextSearchable
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutTextSearchable (0.37.0)
- FlipperKit/FlipperKitNetworkPlugin (0.37.0):
- FlipperKit/FlipperKitLayoutTextSearchable (0.41.5)
- FlipperKit/FlipperKitNetworkPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitReactPlugin (0.37.0):
- FlipperKit/FlipperKitReactPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitUserDefaultsPlugin (0.37.0):
- FlipperKit/FlipperKitUserDefaultsPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/SKIOSNetworkPlugin (0.37.0):
- FlipperKit/SKIOSNetworkPlugin (0.41.5):
- FlipperKit/Core
- FlipperKit/FlipperKitNetworkPlugin
- Folly (2020.01.13.00):
Expand Down Expand Up @@ -346,25 +346,25 @@ DEPENDENCIES:
- DoubleConversion (from `../third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../Libraries/FBReactNativeSpec`)
- Flipper (~> 0.37.0)
- Flipper (~> 0.41.1)
- Flipper-DoubleConversion (= 1.1.7)
- Flipper-Folly (~> 2.2)
- Flipper-Glog (= 0.3.6)
- Flipper-PeerTalk (~> 0.0.4)
- Flipper-RSocket (~> 1.1)
- FlipperKit (~> 0.37.0)
- FlipperKit/Core (~> 0.37.0)
- FlipperKit/CppBridge (~> 0.37.0)
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.37.0)
- FlipperKit/FBDefines (~> 0.37.0)
- FlipperKit/FKPortForwarding (~> 0.37.0)
- FlipperKit/FlipperKitHighlightOverlay (~> 0.37.0)
- FlipperKit/FlipperKitLayoutPlugin (~> 0.37.0)
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.37.0)
- FlipperKit/FlipperKitNetworkPlugin (~> 0.37.0)
- FlipperKit/FlipperKitReactPlugin (~> 0.37.0)
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.37.0)
- FlipperKit/SKIOSNetworkPlugin (~> 0.37.0)
- FlipperKit (~> 0.41.1)
- FlipperKit/Core (~> 0.41.1)
- FlipperKit/CppBridge (~> 0.41.1)
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.41.1)
- FlipperKit/FBDefines (~> 0.41.1)
- FlipperKit/FKPortForwarding (~> 0.41.1)
- FlipperKit/FlipperKitHighlightOverlay (~> 0.41.1)
- FlipperKit/FlipperKitLayoutPlugin (~> 0.41.1)
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.41.1)
- FlipperKit/FlipperKitNetworkPlugin (~> 0.41.1)
- FlipperKit/FlipperKitReactPlugin (~> 0.41.1)
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.41.1)
- FlipperKit/SKIOSNetworkPlugin (~> 0.41.1)
- Folly (from `../third-party-podspecs/Folly.podspec`)
- glog (from `../third-party-podspecs/glog.podspec`)
- RCTRequired (from `../Libraries/RCTRequired`)
Expand Down Expand Up @@ -480,13 +480,13 @@ SPEC CHECKSUMS:
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 8ea0285646adaf7fa725c20ed737c49ee5ea680a
FBReactNativeSpec: e8f07c749b9cf184c819f5a8ca44b91ab61fca12
Flipper: 1670db365568191bd123a0c905b834e77ba9e3d3
Flipper: 33585e2d9810fe5528346be33bcf71b37bb7ae13
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
FlipperKit: afd4259ef9eadeeb2d30250b37d95cb3b6b97a69
FlipperKit: bc68102cd4952a258a23c9c1b316c7bec1fecf83
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
Expand Down

0 comments on commit e5a6655

Please sign in to comment.