从Xcode 11.1升级到Xcode 11.2后,我的应用程序崩溃:
***终止应用程序由于未捕获异常'NSInvalidUnArchiveOperationException',原因:'无法实例化名为_UITextLayoutView的类,因为没有找到名为_UITextLayoutView的类;该类需要在源代码中定义或从库链接(确保该类是正确目标的一部分)'
为什么会发生这种情况?我如何防止这种崩溃?
这个bug在Xcode 11.2.1中是固定的。所以你可以从这里下载和使用它。
包含UITextView的故事板将不再导致应用程序在早于iOS13.2、tvOS 13.2或macOS 10.15.2的操作系统版本上崩溃。(56808566,56873523)
如果您尝试将使用Xcode 11.2构建的应用程序提交到AppStore,您将被拒绝:
App Store Connect操作警告
警告ITMS-90703:“已弃用Xcode构建。由于已解决的应用程序存档问题,我们已于2019年11月5日弃用Xcode 11.2。下载Xcode 11.2.1或更高版本,重建您的应用程序并重新提交。”
因此,使用Xcode 11.2完成的所有解决方法都是无用的
回滚到以前的Xcode发布版本:回滚不再是一个选项,AppStore将拒绝任何低于11.2.1的Xcode构建,看看这个
https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_11.1/Xcode_11.1.xip
请注意,您应该使用Safari下载它,并且您必须首先登录到Apple开发者门户。
您可以在https://developer.apple.com/download/more找到所有其他Xcode版本和其他资源链接(包括发布和beta版本)
这是非常困难但工作的解决方法。将故事板和Sibs中的所有UITextView
替换为纯代码版本。
请注意,此bug由Apple发现并修复
同样早些时候,bug得到了苹果员工埃德福德的证实
UITextView
UITextView
对象前往Objective-C的@aftab muhammed khan答案和Swift适配版本的@MikRo答案
即使最后两个变通方法没有使用Apple私有API,它们也会在AppStore中被拒绝,因为Apple不会接受11.2.1以下Xcode版本的构建!
再一次:
恭喜
Xcode(11.2.1)的新版本现已推出,这是摆脱此问题的最佳方式。
变通方法
@Mojtaba Hosseini我提出的解决方案来自于我对StackOverflow的帮助和参与。你、我和这里的所有其他开发人员已经知道,当苹果公司宣布新版本时,这个问题就会消失。
但除了一切
苹果评论绝对接受了上述解决方案,因为根本不涉及私人API。这种方法非常类似于创建属性,如
@接口UITextView(布局)
或者
UITextView布局. h
因此,当您创建属性时,您直接使用苹果私有组件,并根据您的需求重新调整它们。
简单的例子是AMFNetwork类
- (void)setImageWithURL:(NSURL *)url {
[self setImageWithURL:url placeholderImage:nil];
}
希望我的指控结束了
下面的答案只是我这边的一些帮助,使开发人员能够像您一样继续开发,我们最初建议开发人员回滚Xcode。再次下载8 GB Xcode是一种不好的做法,因为我们都知道新版本的Xcode即将发布。
虽然它在Xcode 11.2.1中已修复,但我有一个Xcode 11.2的解决方案,您可以通过它摆脱此崩溃:
***终止应用程序由于未捕获异常'NSInvalidUnArchiveOperationException',原因:'无法实例化名为_UITextLayoutView的类,因为没有找到名为_UITextLayoutView的类;该类需要在源代码中定义或从库链接(确保该类是正确目标的一部分)'
解决方案
转到构建设置搜索“DEAD_CODE_STRIPPING”并将其设置为否
DEAD_CODE_STRIPPING = NO
然后呢
创建文件UITextViewWork在
UI文本视图解决方法. h
#import <Foundation/Foundation.h>
@interface UITextViewWorkaround : NSObject
+ (void)executeWorkaround;
@end
UI文本视图解决方法. m
#import "UITextViewWorkaround.h"
#import <objc/runtime.h>
@implementation UITextViewWorkaround
+ (void)executeWorkaround {
if (@available(iOS 13.2, *)) {
}
else {
const char *className = "_UITextLayoutView";
Class cls = objc_getClass(className);
if (cls == nil) {
cls = objc_allocateClassPair([UIView class], className, 0);
objc_registerClassPair(cls);
#if DEBUG
printf("added %s dynamically\n", className);
#endif
}
}
}
@end
在应用委托中执行
#import "UITextViewWorkaround.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[UITextViewWorkaround executeWorkaround];
return yes;
}
编译代码,您将拥有一个正在运行的应用程序:)
该问题已在Xcode 11.2.1中修复。
编辑:由于修复程序现已发布,您应该切换到该Xcode版本并注释掉此解决方法。正如Mojtaba Hosseini在他的回答中提到的:
…最后两个变通方法使用的是苹果私人API,将被苹果审查拒绝!
在Apple发布修复程序之前,这是继续开发和测试的好方法。
对于Xcode 11.2,基于Aftab Muhammed Khan的想法并在John Nimis的帮助下,我刚刚测试了以下代码。
无需更改故事板文件!
编辑了我的AppExentate. swift文件并添加了这个类
//******************************************************************
// MARK: - Workaround for the Xcode 11.2 bug
//******************************************************************
class UITextViewWorkaround: NSObject {
// --------------------------------------------------------------------
// MARK: Singleton
// --------------------------------------------------------------------
// make it a singleton
static let unique = UITextViewWorkaround()
// --------------------------------------------------------------------
// MARK: executeWorkaround()
// --------------------------------------------------------------------
func executeWorkaround() {
if #available(iOS 13.2, *) {
NSLog("UITextViewWorkaround.unique.executeWorkaround(): we are on iOS 13.2+ no need for a workaround")
} else {
// name of the missing class stub
let className = "_UITextLayoutView"
// try to get the class
var cls = objc_getClass(className)
// check if class is available
if cls == nil {
// it's not available, so create a replacement and register it
cls = objc_allocateClassPair(UIView.self, className, 0)
objc_registerClassPair(cls as! AnyClass)
#if DEBUG
NSLog("UITextViewWorkaround.unique.executeWorkaround(): added \(className) dynamically")
#endif
}
}
}
}
并在“didFinishLaunchingVideOptions”的委托调用中调用解决方法
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// This is the workaround for Xcode 11.2
UITextViewWorkaround.unique.executeWorkaround()
}