我正在后台线程中测量文本块的高度。出于某种原因,如果在应用程序刚刚启动时发生这种情况,线程会调用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;
}
}
}
我尝试将纯色设置NSColor
为NSTextContainer
前景色,但没有帮助。每次运行应用程序时都不会出现该错误,并且在测试环境中我无法重现该问题。此外,这只是第一次分配文本容器时发生这种情况。