0

バックグラウンド スレッドでテキスト ブロックの高さを測定しています。DynamicColorなんらかの理由で、アプリケーションの起動直後にこれが発生した場合、アプリがダーク モードかどうかをチェックするため、スレッドはメイン スレッドにある必要がある NSColor サブクラスを呼び出します。

バックグラウンド スレッドが実行されているクラスには、 への参照はありませんがDynamicColorNSTextStorageが割り当てられると、 DynamicColor が呼び出されます。バックグラウンド タスクから UI 呼び出しを行うと、エラーが発生します。

が存在することを知らないクラスを呼び出す方法がNSTextStorageわかりません。私のNSDocumentサブクラスだけがそれを参照しており、他のクラスはそれを認識していません。

のバックグラウンド スレッドへの呼び出しNSDocument:

- (void)updatePreviewAndUI:(bool)updateUI {         
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        Preview *preview = [[PreviewCreator alloc] initWithScript:script];
    });
}

バックグラウンド スレッドは、文字列データを含む多数の要素を調べて、それらの高さを計算します。

+ (NSInteger)heightForString:(NSString *)string font:(NSFont *)font maxWidth:(NSInteger)maxWidth lineHeight:(CGFloat)lineHeight
{
    // The error occurs here
    NSTextStorage   *textStorage   = [[NSTextStorage alloc] initWithString:string attributes:@{NSFontAttributeName: font }];
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(maxWidth, MAXFLOAT)];
    [layoutManager addTextContainer:textContainer];
    [textStorage addLayoutManager:layoutManager];
    ...
}

が割り当てられたDynamicColorときに呼び出されます。NSTextStorageでメインスレッドかどうかを確認することでクラッシュは回避できましたDynamicColorが、エラーの原因が気になります。

DynamicColorNSColorサブクラスです。関連する部分は次のとおりです。

#define FORWARD( PROP, TYPE ) \
- (TYPE)PROP { return [self.effectiveColor PROP]; }

- (NSColor *)effectiveColor
{
    if (NSApp) {
        // Call to Application delegate causes the thread error
        if ([(ApplicationDelegate*)[NSApp delegate] isForcedLightMode]) {
            if (self.aquaColor != nil) return self.aquaColor;
        }
        else if ([(ApplicationDelegate*)[NSApp delegate] isForcedDarkMode]) {
            if (self.darkAquaColor != nil) return self.darkAquaColor;
        }
    }
}

前景色を無地にしてみNSColorましたがダメでした。NSTextContainerアプリの実行時に毎回エラーが発生するわけではなく、テスト環境では問題を再現できませんでした。また、これが発生するのは、テキスト コンテナーが割り当てられるのは初めてです。

4

0 に答える 0