Fabric: RCTSurface's start and stop methods

Summary:
The original design of RCTSurface implied that the Surface starts on initialization and stops on deallocation. Recently I realized that this not sufficient API in some cases when the application uses ARC with autorelease pools (that can postpone object deallocations, which is highly undesirable).
And that's simply handy to have those methods sometimes.

Reviewed By: mdvacca

Differential Revision: D9982356

fbshipit-source-id: baa3bd24804d3708606ebd00b8795f2d5c9d4de9
This commit is contained in:
Valentin Shergin 2018-09-26 10:01:54 -07:00 committed by Facebook Github Bot
parent b7584122a1
commit 7420048b63
6 changed files with 71 additions and 4 deletions

View File

@ -114,6 +114,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout;
#pragma mark - Start & Stop
/**
* Starts or stops the Surface.
* Those methods are not implemented yet for regular RCTSurface.
*/
- (BOOL)start;
- (BOOL)stop;
#pragma mark - Mounting/Unmounting of React components
/**

View File

@ -560,6 +560,20 @@
}
}
- (BOOL)start
{
// Does nothing.
// The Start&Stop feature is not implemented for regular Surface yet.
return YES;
}
- (BOOL)stop
{
// Does nothing.
// The Start&Stop feature is not implemented for regular Surface yet.
return YES;
}
#pragma mark - Mounting/Unmounting of React components
- (void)mountReactComponentWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName params:(NSDictionary *)params

View File

@ -27,6 +27,8 @@ typedef NS_OPTIONS(NSInteger, RCTSurfaceStage) {
//
// Surface object was constructed and still valid.
RCTSurfaceStageInitialized = RCTSurfaceStageSurfaceDidInitialize,
// Surface was started.
RCTSurfaceStageStarted = 1 << 8,
// All off-main-thread work is done; we are ready to mount the UI.
RCTSurfaceStagePrepared = RCTSurfaceStageBridgeDidLoad | RCTSurfaceStageModuleDidLoad | RCTSurfaceStageSurfaceDidRun | RCTSurfaceStageSurfaceDidInitialRendering | RCTSurfaceStageSurfaceDidInitialLayout,
// All main-thread work is done, the UI was mounted.

View File

@ -50,6 +50,7 @@ RCT_NOT_IMPLEMENTED(- (nullable instancetype)initWithCoder:(NSCoder *)coder)
{
if (self = [super initWithFrame:CGRectZero]) {
_surface = surface;
[_surface start];
_sizeMeasureMode = sizeMeasureMode;
_surface.delegate = self;
@ -60,6 +61,11 @@ RCT_NOT_IMPLEMENTED(- (nullable instancetype)initWithCoder:(NSCoder *)coder)
return self;
}
- (void)dealloc
{
[_surface stop];
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];

View File

@ -63,6 +63,22 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (RCTSurfaceView *)view;
#pragma mark - Start & Stop
/**
* Starts or stops the Surface.
* A Surface object can be stopped and then restarted.
* The starting process includes initializing all underlying React Native
* infrastructure and running React app.
* Just initialized Surface object starts automatically, there is no need
* to call `start` explicitly. Surface also stops itself on deallocation
* automatically.
* Returns YES in case of success. Returns NO if the Surface is already
* started or stopped.
*/
- (BOOL)start;
- (BOOL)stop;
#pragma mark - Layout: Setting the size constrains
/**

View File

@ -51,19 +51,39 @@
_minimumSize = CGSizeZero;
_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
_stage = RCTSurfaceStageSurfaceDidInitialize;
_touchHandler = [RCTSurfaceTouchHandler new];
[_surfacePresenter registerSurface:self];
_stage = RCTSurfaceStageSurfaceDidInitialize;
[self start];
}
return self;
}
- (BOOL)start
{
if (![self _setStage:RCTSurfaceStageStarted]) {
return NO;
}
[_surfacePresenter registerSurface:self];
return YES;
}
- (BOOL)stop
{
if (![self _unsetStage:RCTSurfaceStageStarted]) {
return NO;
}
[_surfacePresenter unregisterSurface:self];
return YES;
}
- (void)dealloc
{
[_surfacePresenter unregisterSurface:self];
[self stop];
}
#pragma mark - Immutable Properties (no need to enforce synchonization)