diff --git a/React/Base/RCTAssert.h b/React/Base/RCTAssert.h index 7e73aed7d..b0a3c5c52 100644 --- a/React/Base/RCTAssert.h +++ b/React/Base/RCTAssert.h @@ -9,21 +9,7 @@ #import -#ifdef __cplusplus -extern "C" { -#endif - -/** - * By default, only raise an NSAssertion in debug mode - * (custom assert functions will still be called). - */ -#ifndef RCT_ASSERT -#if DEBUG -#define RCT_ASSERT 1 -#else -#define RCT_ASSERT 0 -#endif -#endif +#import "RCTDefines.h" /** * The default error domain to be used for React errors. @@ -44,13 +30,14 @@ typedef void (^RCTAssertFunction)( /** * Private logging function - ignore this. */ -void _RCTAssertFormat(BOOL, const char *, int, const char *, NSString *, ...) NS_FORMAT_FUNCTION(5,6); +RCT_EXTERN void _RCTAssertFormat( + BOOL, const char *, int, const char *, NSString *, ...) NS_FORMAT_FUNCTION(5,6); /** * This is the main assert macro that you should use. */ #define RCTAssert(condition, ...) do { BOOL pass = ((condition) != 0); \ -if (RCT_ASSERT && !pass) { [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \ +if (RCT_NSASSERT && !pass) { [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \ file:@(__FILE__) lineNumber:__LINE__ description:__VA_ARGS__]; } \ _RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \ } while (false) @@ -66,16 +53,12 @@ _RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \ * macros. You can use these to replace the standard behavior with custom log * functionality. */ -void RCTSetAssertFunction(RCTAssertFunction assertFunction); -RCTAssertFunction RCTGetAssertFunction(void); +RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction); +RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void); /** * This appends additional code to the existing assert function, without * replacing the existing functionality. Useful if you just want to forward * assert info to an extra service without changing the default behavior. */ -void RCTAddAssertFunction(RCTAssertFunction assertFunction); - -#ifdef __cplusplus -} -#endif +RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction); diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 0a82b05e2..a37b9ac7d 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -10,6 +10,7 @@ #import #import "RCTBridgeModule.h" +#import "RCTDefines.h" #import "RCTFrameUpdate.h" #import "RCTInvalidating.h" #import "RCTJavaScriptExecutor.h" @@ -40,7 +41,7 @@ typedef NSArray *(^RCTBridgeModuleProviderBlock)(void); /** * This function returns the module name for a given class. */ -extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); +RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass); /** * Async batched bridge used to communicate with the JavaScript application. diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 31a8bea77..40dfceec8 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -143,7 +143,8 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void) // Get data entry NSString *entry = @(*(const char **)(mach_header + addr)); - NSArray *parts = [[entry substringWithRange:(NSRange){2, entry.length - 3}] componentsSeparatedByString:@" "]; + NSArray *parts = [[entry substringWithRange:(NSRange){2, entry.length - 3}] + componentsSeparatedByString:@" "]; // Parse class name NSString *moduleClassName = parts[0]; @@ -164,33 +165,32 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void) } } -#if DEBUG + if (RCT_DEBUG) { - // We may be able to get rid of this check in future, once people - // get used to the new registration system. That would potentially - // allow you to create modules that are not automatically registered + // We may be able to get rid of this check in future, once people + // get used to the new registration system. That would potentially + // allow you to create modules that are not automatically registered - static unsigned int classCount; - Class *classes = objc_copyClassList(&classCount); - for (unsigned int i = 0; i < classCount; i++) - { - Class cls = classes[i]; - Class superclass = cls; - while (superclass) + static unsigned int classCount; + Class *classes = objc_copyClassList(&classCount); + for (unsigned int i = 0; i < classCount; i++) { - if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule))) + Class cls = classes[i]; + Class superclass = cls; + while (superclass) { - if (![RCTModuleClassesByID containsObject:cls]) { - RCTLogError(@"Class %@ was not exported. Did you forget to use RCT_EXPORT_MODULE()?", NSStringFromClass(cls)); + if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule))) + { + if (![RCTModuleClassesByID containsObject:cls]) { + RCTLogError(@"Class %@ was not exported. Did you forget to use RCT_EXPORT_MODULE()?", NSStringFromClass(cls)); + } + break; } - break; + superclass = class_getSuperclass(superclass); } - superclass = class_getSuperclass(superclass); } } -#endif - }); return RCTModuleClassesByID; @@ -289,13 +289,13 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName) _isClassMethod = [reactMethodName characterAtIndex:0] == '+'; _moduleClass = NSClassFromString(_moduleClassName); -#if DEBUG + if (RCT_DEBUG) { - // Sanity check - RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], - @"You are attempting to export the method %@, but %@ does not \ - conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName); -#endif + // Sanity check + RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], + @"You are attempting to export the method %@, but %@ does not \ + conform to the RCTBridgeModule Protocol", objCMethodName, _moduleClassName); + } // Get method signature _methodSignature = _isClassMethod ? @@ -449,20 +449,19 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName) arguments:(NSArray *)arguments context:(NSNumber *)context { + if (RCT_DEBUG) { -#if DEBUG + // Sanity check + RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \ + %@ on a module of class %@", _methodName, [module class]); - // Sanity check - RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \ - %@ on a module of class %@", _methodName, [module class]); -#endif - - // Safety check - if (arguments.count != _argumentBlocks.count) { - RCTLogError(@"%@.%@ was called with %zd arguments, but expects %zd", - RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, - arguments.count, _argumentBlocks.count); - return; + // Safety check + if (arguments.count != _argumentBlocks.count) { + RCTLogError(@"%@.%@ was called with %zd arguments, but expects %zd", + RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, + arguments.count, _argumentBlocks.count); + return; + } } // Create invocation (we can't re-use this as it wouldn't be thread-safe) diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 22cc7ec81..e664f06e0 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -16,6 +16,7 @@ #import "../Views/RCTAnimationType.h" #import "../Views/RCTPointerEvents.h" +#import "RCTDefines.h" #import "RCTLog.h" /** @@ -116,33 +117,25 @@ typedef BOOL css_overflow; @end -#ifdef __cplusplus -extern "C" { -#endif - /** * This function will attempt to set a property using a json value by first * inferring the correct type from all available information, and then * applying an appropriate conversion method. If the property does not * exist, or the type cannot be inferred, the function will return NO. */ -BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json); +RCT_EXTERN BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json); /** * This function attempts to copy a property from the source object to the * destination object using KVC. If the property does not exist, or cannot * be set, it will do nothing and return NO. */ -BOOL RCTCopyProperty(id target, id source, NSString *keyPath); +RCT_EXTERN BOOL RCTCopyProperty(id target, id source, NSString *keyPath); /** * Underlying implementation of RCT_ENUM_CONVERTER macro. Ignore this. */ -NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id); - -#ifdef __cplusplus -} -#endif +RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id); /** * This macro is used for creating simple converter functions that just call diff --git a/React/Base/RCTDefines.h b/React/Base/RCTDefines.h new file mode 100644 index 000000000..71550a30d --- /dev/null +++ b/React/Base/RCTDefines.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +/** + * Make global functions usable in C++ + */ +#if defined(__cplusplus) +#define RCT_EXTERN extern "C" __attribute__((visibility("default"))) +#else +#define RCT_EXTERN extern __attribute__((visibility("default"))) +#endif + +/** + * The RCT_DEBUG macro can be used to exclude error checking and logging code + * from release builds to improve performance and reduce binary size. + */ +#ifndef RCT_DEBUG +#if DEBUG +#define RCT_DEBUG 1 +#else +#define RCT_DEBUG 0 +#endif +#endif + +/** + * The RCT_DEV macro can be used to enable or disable development tools + * such as the debug executors, dev menu, red box, etc. + */ +#ifndef RCT_DEV +#if DEBUG +#define RCT_DEV 1 +#else +#define RCT_DEV 0 +#endif +#endif + +/** + * By default, only raise an NSAssertion in debug mode + * (custom assert functions will still be called). + */ +#ifndef RCT_NSASSERT +#if RCT_DEBUG +#define RCT_NSASSERT 1 +#else +#define RCT_NSASSERT 0 +#endif +#endif diff --git a/React/Base/RCTLog.h b/React/Base/RCTLog.h index 3a8a70d5b..7fa25e6a8 100644 --- a/React/Base/RCTLog.h +++ b/React/Base/RCTLog.h @@ -10,10 +10,7 @@ #import #import "RCTAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif +#import "RCTDefines.h" /** * Thresholds for logs to raise an assertion, or display redbox, respectively. @@ -46,9 +43,9 @@ typedef void (^RCTLogFunction)( ); /** - * Get a given thread's name (or the current queue, iff in debug mode) + * Get a given thread's name (or the current queue, if in debug mode) */ -NSString *RCTThreadName(NSThread *); +RCT_EXTERN NSString *RCTThreadName(NSThread *); /** * A method to generate a string from a collection of log data. To omit any @@ -73,35 +70,35 @@ extern RCTLogFunction RCTDefaultLogFunction; * below which logs will be ignored. Default is RCTLogLevelInfo for debug and * RCTLogLevelError for production. */ -void RCTSetLogThreshold(RCTLogLevel threshold); -RCTLogLevel RCTGetLogThreshold(void); +RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold); +RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void); /** * These methods get and set the current logging function called by the RCTLogXX * macros. You can use these to replace the standard behavior with custom log * functionality. */ -void RCTSetLogFunction(RCTLogFunction logFunction); -RCTLogFunction RCTGetLogFunction(void); +RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction); +RCT_EXTERN RCTLogFunction RCTGetLogFunction(void); /** * This appends additional code to the existing log function, without replacing * the existing functionality. Useful if you just want to forward logs to an * extra service without changing the default behavior. */ -void RCTAddLogFunction(RCTLogFunction logFunction); +RCT_EXTERN void RCTAddLogFunction(RCTLogFunction logFunction); /** * This method adds a conditional prefix to any messages logged within the scope * of the passed block. This is useful for adding additional context to log * messages. The block will be performed synchronously on the current thread. */ -void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix); +RCT_EXTERN void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix); /** * Private logging functions - ignore these. */ -void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4,5); +RCT_EXTERN void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4,5); #define _RCTLog(lvl, ...) do { \ if (lvl >= RCTLOG_FATAL_LEVEL) { RCTAssert(NO, __VA_ARGS__); } \ _RCTLogFormat(lvl, __FILE__, __LINE__, __VA_ARGS__); \ @@ -116,7 +113,3 @@ void _RCTLogFormat(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FU #define RCTLogWarn(...) _RCTLog(RCTLogLevelWarning, __VA_ARGS__) #define RCTLogError(...) _RCTLog(RCTLogLevelError, __VA_ARGS__) #define RCTLogMustFix(...) _RCTLog(RCTLogLevelMustFix, __VA_ARGS__) - -#ifdef __cplusplus -} -#endif diff --git a/React/Base/RCTLog.m b/React/Base/RCTLog.m index 449980fc3..6ca2d4eb8 100644 --- a/React/Base/RCTLog.m +++ b/React/Base/RCTLog.m @@ -11,6 +11,7 @@ #import "RCTAssert.h" #import "RCTBridge.h" +#import "RCTDefines.h" #import "RCTRedBox.h" @interface RCTBridge (Logging) @@ -36,7 +37,7 @@ static void RCTLogSetup() { RCTCurrentLogFunction = RCTDefaultLogFunction; -#if DEBUG +#if RCT_DEBUG RCTCurrentLogThreshold = RCTLogLevelInfo - 1; #else RCTCurrentLogThreshold = RCTLogLevelError; @@ -102,7 +103,7 @@ NSString *RCTThreadName(NSThread *thread) { NSString *threadName = [thread isMainThread] ? @"main" : thread.name; if (threadName.length == 0) { -#if DEBUG +#if DEBUG // This is DEBUG not RCT_DEBUG because it *really* must not ship in RC #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" threadName = @(dispatch_queue_get_label(dispatch_get_current_queue())); @@ -161,12 +162,7 @@ void _RCTLogFormat( NSString *format, ...) { -#if DEBUG - BOOL log = YES; -#else - BOOL log = (RCTCurrentLogFunction != nil); -#endif - + BOOL log = RCT_DEBUG || (RCTCurrentLogFunction != nil); if (log && level >= RCTCurrentLogThreshold) { // Get message @@ -188,17 +184,15 @@ void _RCTLogFormat( level, fileName ? @(fileName) : nil, (lineNumber >= 0) ? @(lineNumber) : nil, message ); -#if DEBUG + if (RCT_DEBUG) { - // Log to red box - if (level >= RCTLOG_REDBOX_LEVEL) { - [[RCTRedBox sharedInstance] showErrorMessage:message]; + // Log to red box + if (level >= RCTLOG_REDBOX_LEVEL) { + [[RCTRedBox sharedInstance] showErrorMessage:message]; + } + + // Log to JS executor + [RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"]; } - - // Log to JS executor - [RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"]; - -#endif - } } diff --git a/React/Base/RCTProfile.h b/React/Base/RCTProfile.h index b3a1683d1..0c254c80a 100644 --- a/React/Base/RCTProfile.h +++ b/React/Base/RCTProfile.h @@ -9,45 +9,47 @@ #import +#import "RCTDefines.h" + /** * RCTProfile * * This file provides a set of functions and macros for performance profiling * - * NOTE: This API is a work in a work in progress, please consider it before - * before using. + * NOTE: This API is a work in a work in progress, please consider carefully + * before before using it. */ -#if DEBUG +#if RCT_DEV /** * Returns YES if the profiling information is currently being collected */ -BOOL RCTProfileIsProfiling(void); +RCT_EXTERN BOOL RCTProfileIsProfiling(void); /** * Start collecting profiling information */ -void RCTProfileInit(void); +RCT_EXTERN void RCTProfileInit(void); /** * Stop profiling and return a JSON string of the collected data - The data * returned is compliant with google's trace event format - the format used * as input to trace-viewer */ -NSString *RCTProfileEnd(void); +RCT_EXTERN NSString *RCTProfileEnd(void); /** * Collects the initial event information for the event and returns a reference ID */ -NSNumber *_RCTProfileBeginEvent(void); +RCT_EXTERN NSNumber *_RCTProfileBeginEvent(void); /** * The ID returned by BeginEvent should then be passed into EndEvent, with the * rest of the event information. Just at this point the event will actually be * registered */ -void _RCTProfileEndEvent(NSNumber *, NSString *, NSString *, id); +RCT_EXTERN void _RCTProfileEndEvent(NSNumber *, NSString *, NSString *, id); /** * This pair of macros implicitly handle the event ID when beginning and ending @@ -69,7 +71,7 @@ _RCTProfileEndEvent(__rct_profile_id, name, category, args) /** * An event that doesn't have a duration (i.e. Notification, VSync, etc) */ -void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *); +RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *); /** * Helper to profile the duration of the execution of a block. This method uses diff --git a/React/Base/RCTProfile.m b/React/Base/RCTProfile.m index 71d34551e..929a026a9 100644 --- a/React/Base/RCTProfile.m +++ b/React/Base/RCTProfile.m @@ -13,10 +13,11 @@ #import +#import "RCTDefines.h" #import "RCTLog.h" #import "RCTUtils.h" -#if DEBUG +#if RCT_DEV #pragma mark - Prototypes diff --git a/React/Base/RCTRedBox.m b/React/Base/RCTRedBox.m index 3bed31505..882a87bfe 100644 --- a/React/Base/RCTRedBox.m +++ b/React/Base/RCTRedBox.m @@ -282,23 +282,14 @@ - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow { - -#if DEBUG - - dispatch_block_t block = ^{ - if (!_window) { - _window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - } - [_window showErrorMessage:message withStack:stack showIfHidden:shouldShow]; - }; - if ([NSThread isMainThread]) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); + if (RCT_DEBUG) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (!_window) { + _window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + } + [_window showErrorMessage:message withStack:stack showIfHidden:shouldShow]; + }); } - -#endif - } - (NSString *)currentErrorMessage diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index d20ba8a5f..812a65122 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -13,43 +13,36 @@ #import #import "RCTAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif +#import "RCTDefines.h" // Utility functions for JSON object <-> string serialization/deserialization -NSString *RCTJSONStringify(id jsonObject, NSError **error); -id RCTJSONParse(NSString *jsonString, NSError **error); +RCT_EXTERN NSString *RCTJSONStringify(id jsonObject, NSError **error); +RCT_EXTERN id RCTJSONParse(NSString *jsonString, NSError **error); // Get MD5 hash of a string (TODO: currently unused. Remove?) -NSString *RCTMD5Hash(NSString *string); +RCT_EXTERN NSString *RCTMD5Hash(NSString *string); // Get screen metrics in a thread-safe way -CGFloat RCTScreenScale(void); -CGSize RCTScreenSize(void); +RCT_EXTERN CGFloat RCTScreenScale(void); +RCT_EXTERN CGSize RCTScreenSize(void); // Round float coordinates to nearest whole screen pixel (not point) -CGFloat RCTRoundPixelValue(CGFloat value); -CGFloat RCTCeilPixelValue(CGFloat value); -CGFloat RCTFloorPixelValue(CGFloat value); +RCT_EXTERN CGFloat RCTRoundPixelValue(CGFloat value); +RCT_EXTERN CGFloat RCTCeilPixelValue(CGFloat value); +RCT_EXTERN CGFloat RCTFloorPixelValue(CGFloat value); // Get current time, for precise performance metrics -NSTimeInterval RCTTGetAbsoluteTime(void); +RCT_EXTERN NSTimeInterval RCTTGetAbsoluteTime(void); // Method swizzling -void RCTSwapClassMethods(Class cls, SEL original, SEL replacement); -void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement); +RCT_EXTERN void RCTSwapClassMethods(Class cls, SEL original, SEL replacement); +RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement); // Module subclass support -BOOL RCTClassOverridesClassMethod(Class cls, SEL selector); -BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector); +RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector); +RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector); // Creates a standardized error object // TODO(#6472857): create NSErrors and automatically convert them over the bridge. -NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData); -NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData); - -#ifdef __cplusplus -} -#endif +RCT_EXTERN NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extraData); +RCT_EXTERN NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData); diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index d2aac3fbe..86444dd2a 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -14,6 +14,7 @@ #import #import "RCTAssert.h" +#import "RCTDefines.h" #import "RCTLog.h" #import "RCTProfile.h" #import "RCTUtils.h" @@ -321,10 +322,9 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) asGlobalObjectNamed:(NSString *)objectName callback:(RCTJavaScriptCompleteBlock)onComplete { - -#if DEBUG - RCTAssert(RCTJSONParse(script, NULL) != nil, @"%@ wasn't valid JSON!", script); -#endif + if (RCT_DEBUG) { + RCTAssert(RCTJSONParse(script, NULL) != nil, @"%@ wasn't valid JSON!", script); + } __weak RCTContextExecutor *weakSelf = self; [self executeBlockOnJavaScriptQueue:RCTProfileBlock((^{ diff --git a/React/Modules/RCTExceptionsManager.m b/React/Modules/RCTExceptionsManager.m index ed30d8741..ece5d0668 100644 --- a/React/Modules/RCTExceptionsManager.m +++ b/React/Modules/RCTExceptionsManager.m @@ -9,6 +9,7 @@ #import "RCTExceptionsManager.h" +#import "RCTDefines.h" #import "RCTLog.h" #import "RCTRedBox.h" #import "RCTRootView.h" @@ -43,11 +44,10 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message return; } -#if DEBUG - - [[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack]; - -#else + if (RCT_DEBUG) { + [[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack]; + return; + } static NSUInteger reloadRetries = 0; const NSUInteger maxMessageLength = 75; @@ -76,21 +76,14 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message NSString *name = [@"Unhandled JS Exception: " stringByAppendingString:sanitizedMessage]; [NSException raise:name format:@"Message: %@, stack: %@", message, prettyStack]; } - -#endif - } RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message stack:(NSArray *)stack) { - -#if DEBUG - - [[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack]; - -#endif - + if (RCT_DEBUG) { + [[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack]; + } } @end diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index e2dc8d560..3f3ea7596 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -18,6 +18,7 @@ #import "RCTAssert.h" #import "RCTBridge.h" #import "RCTConvert.h" +#import "RCTDefines.h" #import "RCTLog.h" #import "RCTProfile.h" #import "RCTRootView.h" @@ -703,20 +704,16 @@ static BOOL RCTCallPropertySetter(NSString *key, SEL setter, id value, id view, ((void (*)(id, SEL, id, id, id))objc_msgSend)(manager, setter, value, view, defaultView); }; -#if DEBUG + if (RCT_DEBUG) { + NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([manager class])); + NSString *logPrefix = [NSString stringWithFormat: + @"Error setting property '%@' of %@ with tag #%@: ", + key, viewName, [view reactTag]]; - NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([manager class])); - NSString *logPrefix = [NSString stringWithFormat: - @"Error setting property '%@' of %@ with tag #%@: ", - key, viewName, [view reactTag]]; - - RCTPerformBlockWithLogPrefix(block, logPrefix); - -#else - - block(); - -#endif + RCTPerformBlockWithLogPrefix(block, logPrefix); + } else { + block(); + } return YES; }