我有一个反应原生应用程序,它运行在React Native 0.51.0,Xcode 9.2上,专门用于iOS 11.X(主要是11.2.5 / 6)iPad专业版。
从0.38.X升级到0.49.X后,我开始注意加载白屏,就像应用程序没有开始加载React Native软件包一样。我已经将React Native升级到0.51.0,但问题仍然存在。
为此问题添加一点颜色,我注意到的一件事是在成功看到应用程序加载到主屏幕后,有一个特定的转换会立即导致再次出现白屏。该问题的日志显示其中一个React Native <Animated.View>
对象存在问题。我注意到我已将RCTAnimation.xcodeproj
添加到父项目中,但libRCTAnimation.a
部分中不再链接Linked Frameworks and Libraries
。将lib添加回链接之后,该特定的白屏消失了,<Animated.View>
正常工作。
此时,我已经三次检查我所包含的所有React Native项目是否正确链接。在这一点上,我不太确定哪些仍然是100%需要,但列表如下(xcodeproj和经过验证的链接库):
这是我的AppDelegate启动代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
CrashReporter.configureCrashReporting()
// Initialize various objects and connections
self.configureApplication()
window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = self.createRootViewController(launchOptions: launchOptions)
self.window?.makeKeyAndVisible()
return true
}
func createRootViewController(launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> UIViewController {
let rootViewController = UIViewController()
rootViewController.view = self.createReactRootView(launchOptions: launchOptions)
return rootViewController
}
func createReactRootView(launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> UIView? {
let jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index.ios", fallbackResource: nil)
let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "app", initialProperties: nil, launchOptions: launchOptions)
rootView?.backgroundColor = .white
return rootView
}
答案 0 :(得分:0)
白色屏幕的两个例子(这是一个很长的解决方案......)
白色屏幕#1:
在某些时候,React Native不再允许<Image>
视图生成子项。当应用程序达到我们将{child}添加到<Image>
个视图的状态时,屏幕将变为白色。这至少会在日志中跟上一个指示问题的打印声明。
白色屏幕#2(主屏幕):
从iOS 11开始,我们在从主线程调用DispatchQueue.main.async {}
时发现了不同的行为。这似乎已经成熟,可以创造死锁情况(我们确实让这个东西在没有进展的情况下运行了几个小时);也许这是Apple的Dispatch Queuing系统中的一个错误?
我们的一个React Native桥接对象在其构造函数内部调用DispatchQueue.main.async {}
。这永远不会完成,阻塞主线程,因此React Native的其余部分将不会继续加载(它甚至无法加载该包)。什么都不会打印,暂停调试器永远不会产生可用的状态。
我们只是删除了包裹DispatchQueue.main.async {}
并正在调用这些语句,因为它已经在主线程上。