从 Xcode 11.1 升级到 Xcode 11.2 后,应用程序因 _UITextLayoutView 而崩溃

Posted

技术标签:

【中文标题】从 Xcode 11.1 升级到 Xcode 11.2 后,应用程序因 _UITextLayoutView 而崩溃【英文标题】:After upgrading to Xcode 11.2 from Xcode 11.1, app crashes due to _UITextLayoutView 【发布时间】:2020-02-27 14:59:12 【问题描述】:

从 Xcode 11.1 升级到 Xcode 11.2 后,我的应用崩溃了:

*** 由于未捕获的异常“NSInvalidUnarchiveOperationException”而终止应用程序,原因:“无法实例化名为 _UITextLayoutView 的类,因为找不到名为 _UITextLayoutView 的类;该类需要在源代码中定义或从库中链接(确保该类是正确目标的一部分)'

为什么会这样?如何防止这种崩溃?

【问题讨论】:

似乎是 Xcode 11.2 的错误。检查线程 forums.developer.apple.com/thread/125287 。很可能与层次结构中的 TextViews 相关 @DanielStorm 不幸的是,这没有帮助。我刚刚将一个普通的 UITextView 添加到一个以前没有的屏幕上(并且之前也没有崩溃:))。现在它崩溃并出现同样的错误。除最新的 ios 13.2 外,所有设备/模拟器都存在此问题 有人知道在 iOS 13.1.2 设备上运行时这是否会导致使用 Xcode 11.2 构建的生产应用程序崩溃? 这是一个非常好的问题,因此有 198 票,所以我真的不知道为什么有人将其标记为“暂缓不清楚” @MikeVolmar 我投票决定关闭并且不再相关。它已在 11.2.1 中修复。这个问题的用处很短。 【参考方案1】:

更新:已修复! ??

唯一的解决办法是更新

这个 bug 在 Xcode 11.2.1 中是 fixed。所以你可以download and use it from here.

包含 UITextView 的故事板将不再导致应用在 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下载它,你必须先login to Apple developer portal。

您可以在https://developer.apple.com/download/more 找到所有其他 Xcode 版本和其他资源链接(包括发行版和测试版)

解决方法

这是非常困难但可行的解决方法。 将 storyboardXib 中的所有 UITextViews 替换为 纯代码 版本。


请注意这个bug is found and fixed by Apple

同样早些时候,the bug 被Apple Staff edford 确认


对于那些使用 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 弃用

【讨论】:

伤心,但解决方案对我有用。谢谢! 11.1 作品。我不建议转换为纯代码,因为我敢打赌很快就会有修复。如果您不介意:一旦有新版本可用,请更新此答案。如果人们开始下载 11.1 事件会很糟糕,尽管那里有一个固定版本:) 我已经有 11.1 但没用,我没有升级到 11.2。 请注意,您可能应该从您的开发设备中删除该应用程序和/或清理 Xcode 的构建文件夹 (CMD + Shift + K) 如何升级到 v11.2.1 ?它没有出现在应用商店中。从开发者门户下载 GM 种子会尝试将应用程序全部下载大约 8gb! 另外,如果它已被弃用,为什么苹果现在不直接从应用商店中删除 11.2?【参考方案2】:

恭喜

新版 Xcode (11.2.1) 现已推出,这是解决此问题的最佳方法。

解决方法

@Mojtaba Hosseini 我提出的解决方案来自我身边对 *** 开发人员的帮助和参与。你、我和这里的所有其他开发者都已经知道,当苹果宣布新版本时,这个问题就会消失。

但除此之外

上述解决方案肯定被 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;
    

编译代码,您将拥有一个正在运行的应用程序:)

【讨论】:

如果它对您有用,请排名,以便其他人也可以尝试此解决方案 @Hardy_Germany 我对此进行了一些测试,对于 Swift,您可以尝试: class UITextViewWorkaround: NSObject class func executeWorkaround() if #available(iOS 13.2, *) else let className = " _UITextLayoutView" var cls = objc_getClass(className) if cls == nil cls = objc_allocateClassPair(UIView.self, className, 0) objc_registerClassPair(cls as! AnyClass) #if DEBUG print(" added %@ dynamic\n", className) ; #endif @DaveDude DEAD_CODE_STRIPPING = 如果您将 Swift 包管理器与 Xcode 11.2 一起使用,则需要 NO @pradipsutariya 是的,当然,为什么我们不改变 APPLE CLASSES 中的任何内容。 仅发布 Xcode 11.2.1 GM 种子(测试版)。稳定版即将发布。【参考方案3】:

该问题已在 Xcode 11.2.1 中修复。

编辑:由于修复程序现已发布,您应该切换到该 Xcode 版本并注释掉此解决方法。正如 Mojtaba Hosseini 在他的回答中提到的那样:

...这最后两个令人费解的解决方法正在使用 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()

【讨论】:

【参考方案4】:

我已将 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!

【讨论】:

我们需要在哪里添加这段代码?在委托文件中? @SIDHARTHPU 你可以打电话给didFinishLaunchingWithOptions 在这个问题上尝试了各种修复方法,但直到 Xcode 11.3 才成功?!谢谢! 这是最简短最出色的解决方案! @LalKrishna 创建名为 UITextViewWorkaround.swift 的新文件并将上述代码添加到其中。然后在 return 语句之前将 UITextViewWorkaround.executeWorkaround() 这个添加到 didFinishLaunchingWithOptions 中。【参考方案5】:

更快的修复:

///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

注意:您将丢失在情节提要中创建的所有属性。这可能会产生严重影响(例如委托设置、大小等)

【讨论】:

这似乎是朝着解决方法迈出的良好一步,但还不是一个解决方案......【参考方案6】:

更新的解决方案: 更新到 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 时,也修复了崩溃问题。

【讨论】:

这是最简单的修复方法 - 将 iPhone iOS 升级到 13.2 升级 iOS 显然不是解决方案,因为 OP 是从开发人员的角度来讨论的。 Apple 确认该错误发生在 13.2 之前的 iOS 版本和 Xcode 11.2 中。 将 XCode 降级到版本 11.1 (11A1027) -- 仍然有同样的崩溃 ( 如果您升级或降级,但它仍然会根据 Wojteck 下面的评论使干净的 Xcode 的构建文件夹 (CMD + Shift + K) 崩溃,这在升级时为我解决了这个问题【参考方案7】:

11.2.1 转基因种子解决了这个问题

(可用于发布到 App Store)

转到https://developer.apple.com/download/。下载Xcode 11.2.1 GM种子

Release notes 确认它修复了这个错误:

【讨论】:

请注意,安装 Xcode 11.2.1 GM 种子后,您可能应该从开发设备中删除该应用程序和/或清理 Xcode 的构建文件夹(CMD + Shift + K)。【参考方案8】:

您可以从 Apple 开发者网站下载最新的 Xcode beta 版本(11.2.1 GM)。

Here the direct link

【讨论】:

请注意,安装 Xcode 11.2.1 GM 种子后,您可能应该从开发设备中删除该应用程序和/或清理 Xcode 的构建文件夹(CMD + Shift + K)。 安装并运行,无需任何其他过程。问题已解决✌️ 如何安装这个?它给了我一个文件夹,但没有可执行文件 只需从提供的链接下载 zip 并解压即可。然后将应用程序复制到应用程序文件夹中。 问题是当我提取它时,我得到两个文件,内容和元数据......这就是为什么我问如何处理它们。我使用了存档实用程序,因为通常单击它会失败。我再试一次【参考方案9】:

改进@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)
        
    

【讨论】:

完美运行。 @garafajon 的代码在意想不到的地方引起了盒子的问题。这解决了这些问题~干得好!【参考方案10】:

作为“快速”修复,您可以直接从代码中添加UITextView,而不是通过 IB。至少它对我有用。虽然从我的角度来看,最好回滚到以前的 Xcode/等待新的。

【讨论】:

【参考方案11】:

这是 Xcode 11.2 的一个错误。子类化 Textview 在所有未安装新版 iOS 版本 (13.2) 的设备上崩溃。您最好不要使用该版本构建版本。

您现在可以:

将 Xcode 降级到 11.1 或 将您的设备升级到 iOS 13.2

【讨论】:

那么这个bug是否只影响子类文本视图? 在更新 Xcode 时更新 iOS 可解决问题。 问题是,如果每个 iOS 小于 13.2 的已发布应用都会发生崩溃...我不敢尝试...【参考方案12】:

我使用了一个成功的解决方法,但它很痛苦。这是我遵循的过程:

    在文本编辑器中打开 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"  />
  <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 可以替换。否则,这将变得站不住脚。

【讨论】:

【参考方案13】:

我刚刚将 Xcode 11.2 升级到 11.2.1 时遇到了同样的问题,它运行良好。

升级后,我在 iOs 13 和 iOS 12 上进行了相同的测试,并且运行良好。

【讨论】:

BossOz 答案的副本。【参考方案14】:

1。问题:

Xcode 11.2 存在一个问题,如果使用 Xcode 11.2 编译,包含 UITextView 的 Storyboard 将导致应用在 iOS 13.2 之前的操作系统版本上崩溃。

检查此apple documentation。

2。解决方案:

唯一的解决方案是将您的 Xcode 更新为 11.2.1 或 11.3.

Xcode 11.2.1 专门发布以修复此崩溃问题。

检查这个apple documentation.

3。建议:

我建议您使用最新版本的 Xcode 11.3,因为它支持为 iOS 13.3 开发应用程序并且还有许多新功能。 检查这个apple documentation。

【讨论】:

【参考方案15】:

此问题已在 Xcode 11.2.1 版中修复,并在发行说明中注明:

此更新修复了一个可能导致使用 UITextView 的应用崩溃的关键问题

【讨论】:

以上是关于从 Xcode 11.1 升级到 Xcode 11.2 后,应用程序因 _UITextLayoutView 而崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Swift UI Canvas 未在 macOS 10.15 和 Xcode 11.1 中显示

Xcode 11.2 和 11.2.1 GM SEED -- 无法安装到设备

Xcode 11.1 GM 发布,这可能才是真正的 Xcode 11;Swift 5.2 正式提上日程

Xcode 11.1 错误:产生多个命令

Xcode 11.1如何安装iOS14模拟器?

在 Mac OS 11.1 中运行 Xcode 12.3 项目时您无权保存文件