从 Xcode 11.1 升级到 Xcode 11.2 后,我的应用程序崩溃:
*** 由于未捕获的异常“NSInvalidUnarchiveOperationException”而终止应用程序,原因:“无法实例化名为 _UITextLayoutView 的类,因为找不到名为 _UITextLayoutView 的类;该类需要在源代码中定义或从库中链接(确保该类是正确目标的一部分)'
为什么会这样?我怎样才能防止这种崩溃?
更新:已修复! 🎉🎊
唯一的解决方案是更新
这个 bug 在 Xcode 11.2.1 中是 fixed。所以您可以download and use it from here.
包含 UITextView 的 Storyboard 将不再导致应用在 iOS 13.2、tvOS 13.2 或 macOS 10.15.2 之前的操作系统版本上崩溃。 (56808566, 56873523)
Xcode 11.2 于 2019 年 11 月 5 日被 Apple 弃用
如果您尝试将使用 Xcode 11.2 构建的应用程序提交到 AppStore,您将被拒绝:
App Store Connect 操作警告
警告 ITMS-90703:“已弃用 Xcode Build。由于已解决应用存档问题,我们已于 2019 年 11 月 5 日弃用 Xcode 11.2。下载 Xcode 11.2.1 或更新版本,重新构建您的应用并重新提交。”
因此,使用 Xcode 11.2 完成的所有解决方法都是无用的
这是 Xcode 11.2 的错误,并在 Xcode 11.2.1 中修复。
解决方案
从以下位置回滚到以前的 Xcode 发布版本: 回滚不再是一种选择,AppStore 将拒绝任何 Xcode 低于 11.2.1 的构建take a look at this
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 版本和其他资源链接(包括发行版和测试版)
解决方法
这是非常困难但可行的解决方法。将 storyboard 和 Xib 中的所有 UITextView
替换为 纯代码 版本。
请注意此bug is found and fixed by Apple
https://i.stack.imgur.com/OhSdh.png
同样早些时候,the bug 已被 Apple Staff edford 确认
https://i.stack.imgur.com/mptit.png
对于那些使用 iOS 13.2 并且不能再使用 Xcode 11.1 的用户:
将 macOS 更新到 10.15.1 或更高版本 安装 Xcode 11.2.1 或更高版本 它现在应该可以在更新的设备上使用。
对于那些有故事板的人:
子类 UITextView 将其分配给所有 UITextView 对象不要忘记更新任何可能在子类化中丢失的属性更改。
对于那些对方法调配(Objc 和动态行为)感到满意的人
前往 @aftab muhammed khan answer for Objective-C 和 @MikRo answer for Swift adapted version
只是不要再这样做了:
即使这最后两个灵活的解决方法没有使用 Apple 私有 API,它们也会在 AppStore 中被拒绝,因为Apple will not accept builds with Xcode versions under 11.2.1!
再一次:
Xcode 11.2 于 2019 年 11 月 5 日被 Apple 弃用
祝贺
新版本的 Xcode (11.2.1) 现已推出,这是摆脱此问题的最佳方法。
解决方法
@Mojtaba Hosseini 我提出的解决方案来自我对 StackOverflow 开发人员的帮助和参与。你、我和这里的所有其他开发者都已经知道,当苹果宣布新版本时,这个问题就会消失。
但除了一切
上述解决方案肯定被 Apple Review 接受,因为根本不涉及私有 API。这种方法与创建属性非常相似,例如
@interface UITextView(布局)
或者
UITextView+Layout.h
因此,当您创建属性时,您将直接使用 APPLE 私有组件并根据您的依赖或要求重新调制它们。
简单示例是 AMFNetworking 类
- (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”并将其设置为 NO
DEAD_CODE_STRIPPING = NO
然后
创建文件 UITextViewWorkaround
UITextViewWorkaround.h
#import <Foundation/Foundation.h>
@interface UITextViewWorkaround : NSObject
+ (void)executeWorkaround;
@end
UITextViewWorkaround.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 在他的回答中提到的那样:
...这最后两个 swizzling 变通办法正在使用 Apple 私有 API,将被 Apple 审查拒绝!
在 Apple 发布修复程序之前,这是继续开发和测试的一个很好的解决方法。
对于 Xcode 11.2,基于 Aftab Muhammed Khan 的想法并在 John Nimis 的帮助下,我刚刚测试了以下代码。
无需更改情节提要文件!
编辑了我的 AppDelegate.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
}
}
}
}
并在对“didFinishLaunchingWithOptions”的委托调用中调用解决方法
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()
}
我已经将 khan 的 Obj-C 解决方案改编为 Swift:
import UIKit
@objc
class UITextViewWorkaround : NSObject {
static func executeWorkaround() {
if #available(iOS 13.2, *) {
} else {
let className = "_UITextLayoutView"
let theClass = objc_getClass(className)
if theClass == nil {
let classPair: AnyClass? = objc_allocateClassPair(UIView.self, className, 0)
objc_registerClassPair(classPair!)
}
}
}
}
在 AppDelegate
中 didFinishLaunchingWithOptions
的末尾调用它。
谢谢@Aftab!
didFinishLaunchingWithOptions
中调用它
更快的修复:
///Substitute class for _UITextLayoutView bug
class FixedTextView: UITextView {
required init?(coder: NSCoder) {
if #available(iOS 13.2, *) {
super.init(coder: coder)
}
else {
let rect = CGRect(origin: .zero, size: CGSize(width: 100, height: 44*3))
super.init(frame: rect, textContainer: nil)
}
}
}
在某处添加此代码,然后将所有情节提要实例替换为 FixedTextView
。
注意:您将丢失在情节提要中创建的所有属性。这可能会产生严重的影响(例如委托设置、大小等)
更新的解决方案:更新到 Xcode 11.2.1。它适用于我的 iOS 11、12 或 13 设备。
请参阅 apple's documentation 此更新修复了可能导致使用 UITextView 的应用程序崩溃的关键问题。
旧解决方案: 从 https://developer.apple.com/download/more/ 下载 Xcode 11.1 从 11.2 切换回 11.1 修复了崩溃问题。
此外,对我来说,即使使用 Xcode 11.2,当我将 iPhone 升级到 13.2 时,也修复了崩溃问题。
11.2.1 转基因种子解决了这个问题
(可用于发布到 App Store)
转到https://developer.apple.com/download/。下载 Xcode 11.2.1 GM 种子
发行说明确认它修复了这个错误:
https://i.stack.imgur.com/ZAgaf.png
您可以从 Apple 开发者网站下载最新的 Xcode beta 版本(11.2.1 GM)。
https://i.stack.imgur.com/gQGMC.png
改进@garafajon 的答案。对我来说,它在大多数情况下都有效。
///Substitute class for _UITextLayoutView bug
class FixedTextView: UITextView {
required init?(coder: NSCoder) {
if #available(iOS 13.2, *) {
super.init(coder: coder)
}
else {
super.init(frame: .zero, textContainer: nil)
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.contentMode = .scaleToFill
self.isScrollEnabled = false // causes expanding height
// Auto Layout
self.translatesAutoresizingMaskIntoConstraints = false
self.font = UIFont(name: "HelveticaNeue", size: 18)
}
}
}
作为“快速”修复,您可以直接从代码中添加 UITextView
,而不是通过 IB。至少它对我有用。虽然从我的角度来看,最好回滚到以前的 Xcode/等待新的 Xcode。
这是 Xcode 11.2 的一个错误。子类化的 Textview 在所有未安装新版 iOS 版本 (13.2) 的设备上都会崩溃。您可能最好不要使用该版本构建版本。
你现在可以:
将 Xcode 降级到 11.1 或
将您的设备升级到 iOS 13.2
我使用了一个成功的解决方法,但它很痛苦。这是我遵循的过程:
在文本编辑器中打开 XIB 找到有问题的 TextView。就我而言:
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="782-j1-88c" customClass="LCAnsiConsoleTextView">
<rect key="frame" x="16" y="20" width="343" height="589"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="12"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
注意它的 id(在我的例子中:id="782-j1-88c")覆盖上面答案中提到的类并重新创建选项(我的是 Objective-C,对不起):
@implementation FixedTextView
- (id) initWithCoder:(NSCoder*)coder
{
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){13,2,0}])
self = [super initWithCoder:coder];
else {
self = [super initWithFrame:CGRectMake(16, 3, 343, 605)];
self.editable = YES;
self.selectable = YES;
self.insetsLayoutMarginsFromSafeArea = YES;
self.clipsToBounds = YES;
self.clearsContextBeforeDrawing = YES;
self.autoresizesSubviews = YES;
self.contentMode = UIViewContentModeScaleToFill;
self.scrollEnabled = YES;
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = YES;
self.translatesAutoresizingMaskIntoConstraints = NO;
self.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0];
}
return self;
}
请注意包含您的文本视图 ID 的约束,并针对您的视图或视图控制器中的其他元素 ID 重新创建这些约束。就我而言:
- (id) initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self xibSetup];
[self initView];
/*
<constraint firstItem="75C-lt-YtE" firstAttribute="top" secondItem="782-j1-88c" secondAttribute="bottom" constant="8" symbolic="YES" id="8SH-5l-FAs"/>
<constraint firstItem="782-j1-88c" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" id="Mve-aZ-HCe"/>
<constraint firstItem="782-j1-88c" firstAttribute="leading" secondItem="75C-lt-YtE" secondAttribute="leading" id="dPG-u3-cCi"/>
<constraint firstItem="782-j1-88c" firstAttribute="trailing" secondItem="iN0-l3-epB" secondAttribute="trailingMargin" id="sjT-0Q-hNj"/>
<constraint firstItem="782-j1-88c" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="vic-vZ-osR"/>
*/
[self.command.topAnchor constraintEqualToAnchor:self.console.bottomAnchor constant:8].active = YES;
[self.console.leadingAnchor constraintEqualToAnchor:self.layoutMarginsGuide.leadingAnchor].active = YES;
[self.console.leadingAnchor constraintEqualToAnchor:self.command.leadingAnchor].active = YES;
[self.console.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = YES;
[self.console.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
}
return self;
}
这样做为我解决了这个问题,而不会丢失所需的功能。幸运的是,我只有一个 UITextView
可以替换。否则,这将变得站不住脚。
我遇到了同样的问题,我刚刚将 Xcode 11.2 升级到 11.2.1,它运行良好。
升级后,我在 iOs 13 和 iOS 12 上进行了相同的测试,并且运行良好。
1.问题:
Xcode 11.2 存在一个问题,如果使用 Xcode 11.2 编译,包含 UITextView 的 Storyboard 将导致应用程序在早于 iOS 13.2 的操作系统版本上崩溃。
https://i.stack.imgur.com/ocZeY.png
2.解决方法:
唯一的解决方案是将您的 Xcode 更新为 11.2.1 或 11.3.
Xcode 11.2.1 专门发布以修复此崩溃问题。
https://i.stack.imgur.com/uCp04.png
三、建议:
我建议您使用最新版本的 Xcode 11.3,因为它支持为 iOS 13.3 开发应用程序并且还有许多新功能。检查此apple documentation。
此问题已在 Xcode 版本 11.2.1 中修复,并在发行说明中指出:
此更新修复了一个可能导致使用 UITextView 的应用程序崩溃的关键问题
https://i.stack.imgur.com/sy65R.png
CMD + Shift + K
)