1. ホーム
  2. アイオス

[解決済み】Xcode 11.1からXcode 11.2にアップグレードした後、_UITextLayoutViewが原因でアプリがクラッシュする。

2022-03-25 15:18:05

質問

Xcode 11.1からXcode 11.2にアップグレードした後、アプリがクラッシュしてしまいます。

*** キャッチできない例外 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named _UITextLayoutView because no class named _UITextLayoutView was found; must be defined in source code or linked in from library (ensure the class is part of correct target)' によりアプリを終了します。

なぜこのようなことが起こるのでしょうか?どうすればこのクラッシュを防ぐことができますか?

解決方法を教えてください。

おめでとうございます

Xcodeの新バージョン(11.2.1)がリリースされており、この問題を解決する最善の方法です。

回避策

モジタバ・ホッセイニ 私が提案した解決策は、私の側からStackOverflowの開発者仲間に助けを求め、参加してもらったものです。Appleから新バージョンが発表されれば、この問題はなくなることは、あなたも私も、ここにいる他のすべての開発者も、すでに知っていることです。

しかし、すべての横で

前述の解決策は、プライベートAPIが全く関係ないため、Apple Reviewに間違いなく受け入れられました。この方法は、以下のようなプロパティを作成するのと非常に似ています。

インターフェース UITextView (Layout)

または

UITextView+Layout.h

つまり、プロパティを作成するときは、APPLE Private Componentsを直接使用し、依存や要件に応じてそれらを再モジュールしているのです。

簡単な例として、AMFNetworkingクラスがあります。

- (void)setImageWithURL:(NSURL *)url {
    [self setImageWithURL:url placeholderImage:nil];
}

疑惑の解消を願う

以下の回答は、当初、開発者にXcodeをロールバックするよう提案しましたが、開発者が開発を継続できるようにするための私の側からの支援です。8GBのXcodeを再度ダウンロードするのは、新しいXcodeがすぐにリリースされることがわかっているため、悪い習慣でした。

Xcode 11.2.1では修正されていますが、Xcode 11.2用にこのクラッシュを取り除くことができる解決策を1つ得ました。

<ブロッククオート

*** キャッチできない例外 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named _UITextLayoutView because no class named _UITextLayoutView was found; must be defined in source code or linked in from library (ensure the class is part of correct target)' によりアプリを終了します。

解決方法

ビルド設定から、"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;
    }

このコードをコンパイルすると、アプリが動作するようになります :)