0

我正在后台线程中测量文本块的高度。出于某种原因,如果在应用程序刚刚启动时发生这种情况,线程会调用DynamicColor需要在主线程中调用的 NSColor 子类,因为它会检查应用程序是否处于暗模式。

后台线程正在运行的类不应该对 有任何引用DynamicColor,但是,当NSTextStorage分配 时,会调用 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,但我担心错误的原因。

DynamicColor是一个NSColor子类。以下是相关部分:

#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;
        }
    }
}

我尝试将纯色设置NSColorNSTextContainer前景色,但没有帮助。每次运行应用程序时都不会出现该错误,并且在测试环境中我无法重现该问题。此外,这只是一次分配文本容器时发生这种情况。

4

0 回答 0