提问者:小点点

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


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

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

为什么会发生这种情况?我如何防止这种崩溃?


共3个答案

匿名用户

这个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得到了苹果员工埃德福德的证实

  1. 将macOS更新到10.15.1或更高版本
  2. 安装Xcode 11.2.1或更高版本
  3. 它现在应该在更新的设备上工作。
  1. 子类UITextView
  2. 将其分配给所有UITextView对象
  3. 不要忘记更新子类化中可能丢失的任何属性更改。

前往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()
}