gpt4 book ai didi

cocoa - 如何在用户滚动时更新 NSTextView(不崩溃)

转载 作者:行者123 更新时间:2023-12-03 16:51:11 28 4
gpt4 key购买 nike

我使用 NSTextView 来显示长搜索的结果,其中使用后台线程找到行时添加行

[self performSelectorOnMainThread: @selector(addMatch:) 
withObject:options waitUntilDone:TRUE];

作为我的更新例程

-(void)addMatch:(NSDictionary*)options{
...
NSTextStorage* store = [textView textStorage];
[store beginEditing];
[store appendAttributedString:text];
...
[store endEditing];
}

这工作正常,直到用户在更新时滚动浏览匹配项,此时会出现异常

-[NSLayoutManager _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] *** attempted layout while textStorage is editing. It is not valid to cause the layoutManager to do layout while the textStorage is editing (ie the textStorage has been sent a beginEditing message without a matching endEditing.)

在布局调用中:

    0   CoreFoundation                      0x00007fff92ea364c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8acd16de objc_exception_throw + 43
2 CoreFoundation 0x00007fff92ea34fd +[NSException raise:format:] + 205
3 UIFoundation 0x00007fff8fe4fbc1 -[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 641
4 UIFoundation 0x00007fff8fe5970c _NSFastFillAllLayoutHolesForGlyphRange + 1493
5 UIFoundation 0x00007fff8fda8821 -[NSLayoutManager lineFragmentRectForGlyphAtIndex:effectiveRange:] + 39
6 AppKit 0x00007fff8ef3cb02 -[NSTextView _extendedGlyphRangeForRange:maxGlyphIndex:drawingToScreen:] + 478
7 AppKit 0x00007fff8ef3ba97 -[NSTextView drawRect:] + 1832
8 AppKit 0x00007fff8eed9a09 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 1186
9 AppKit 0x00007fff8eed9458 __46-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke + 218
10 AppKit 0x00007fff8eed91f1 -[NSView(NSLayerKitGlue) _drawViewBackingLayer:inContext:drawingHandler:] + 2407
11 AppKit 0x00007fff8eed8873 -[NSView(NSLayerKitGlue) drawLayer:inContext:] + 108
12 AppKit 0x00007fff8efaafd2 -[NSTextView drawLayer:inContext:] + 179
13 AppKit 0x00007fff8ef22f76 -[_NSBackingLayerContents drawLayer:inContext:] + 145
14 QuartzCore 0x00007fff9337c177 -[CALayer drawInContext:] + 119
15 AppKit 0x00007fff8ef22aae -[_NSTiledLayer drawTile:inContext:] + 625
16 AppKit 0x00007fff8ef227df -[_NSTiledLayerContents drawLayer:inContext:] + 169
17 QuartzCore 0x00007fff9337c177 -[CALayer drawInContext:] + 119
18 AppKit 0x00007fff8f6efd64 -[NSTileLayer drawInContext:] + 169
19 QuartzCore 0x00007fff9337b153 CABackingStoreUpdate_ + 3306
20 QuartzCore 0x00007fff9337a463 ___ZN2CA5Layer8display_Ev_block_invoke + 59
21 QuartzCore 0x00007fff9337a41f x_blame_allocations + 81
22 QuartzCore 0x00007fff93379f1c _ZN2CA5Layer8display_Ev + 1546
23 AppKit 0x00007fff8ef226ed -[NSTileLayer display] + 119
24 AppKit 0x00007fff8ef1ec34 -[_NSTiledLayerContents update:] + 5688
25 AppKit 0x00007fff8ef1d337 -[_NSTiledLayer display] + 375
26 QuartzCore 0x00007fff93379641 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 603
27 QuartzCore 0x00007fff93378d7d _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
28 QuartzCore 0x00007fff9337850e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
29 QuartzCore 0x00007fff93378164 _ZN2CA11Transaction6commitEv + 390
30 QuartzCore 0x00007fff93388f55 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 71
31 CoreFoundation 0x00007fff92dc0d87 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
32 CoreFoundation 0x00007fff92dc0ce0 __CFRunLoopDoObservers + 368
33 CoreFoundation 0x00007fff92db2f1a __CFRunLoopRun + 1178
34 CoreFoundation 0x00007fff92db2838 CFRunLoopRunSpecific + 296
35 UIFoundation 0x00007fff8fdfe744 -[NSHTMLReader _loadUsingWebKit] + 2097
36 UIFoundation 0x00007fff8fdffb55 -[NSHTMLReader attributedString] + 22
37 UIFoundation 0x00007fff8fe12cca _NSReadAttributedStringFromURLOrData + 10543
38 UIFoundation 0x00007fff8fe10306 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 115

考虑到一切都在 beginEditing 和 endEditing 之间,出了什么问题?

最佳答案

从堆栈跟踪(不完整)来看,运行循环源似乎在不合时宜的时刻触发。

NSAttributedString 使用 WebKit 解析 HTML。 WebKit 有时会运行运行循环。对于一般情况,可能需要从网络获取资源才能正确渲染。由于这需要时间,因此它运行运行循环来等待结果并同时处理其他事情。

其他运行循环源之一似乎是核心动画源,用于执行某些动画的下一步(可能是滚动 TextView )。

您没有显示 beginEditingendEditing 之间的所有代码。我怀疑您已经从 HTML 或从这两个位置之间的 URL 获取的数据构造了一个 NSAttributedString 。这允许核心动画运行循环源触发。这要求 TextView 进行绘制,要求其布局管理器布置文本。这种情况发生在 beginEditing 之后但 endEditing 之前,这是异常的原因。

因此,请尝试重新排序代码,以在 beginEditing 之前构造所有 NSAttributedString

并向 Apple 提交错误。在我看来,当 NSAttributeString 使用 WebKit 渲染 HTML 时,它需要使 WebKit 使用私有(private)运行循环模式,这样其他源就无法触发。他们可能更喜欢不同的解决方案,但错误是真实的。

关于cocoa - 如何在用户滚动时更新 NSTextView(不崩溃),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28015566/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com