我们有一个NSTableRowView的子类,该子类将覆盖drawSelectionInRect:(在内部由drawRect:调用)。此方法需要访问NSManagedObjectContext,因此作为健全性检查,我们在那里有一个断言,说我们在主线程中。现在事实证明,有时Apple会从非主线程调用drawRect(下面的示例堆栈跟踪)。这是否意味着它甚至可以同时从两个不同的线程中执行此操作? IE。覆盖drawRect:并使用数据模型时,我们必须自己照顾线程安全性?

错误:声明失败:[NSThread isMainThread]:(ZS_AppDelegate.m:1287)
(
0 tomedo_kunden 0x00000001008af46a-[ZS_AppDelegate loggingInUser] + 554
1 tomedo_kunden 0x00000001016feca7 + [Nutzer登录用户] + 71
2 tomedo_kunden 0x0000000100f33397 + [ZSUserDefaults(MacOS)colorFromPreferences:] + 167
3 tomedo_kunden 0x00000001003d8265-[Besuch(BesuchCategory)baseTextColor] + 101
4 tomedo_kunden 0x000000010071f846-[ZSTableRowView drawSelectionInRect:] + 806
5 AppKit 0x00007fffd189d26c-[NSTableRowView drawRect:] + 242
6 AppKit 0x00007fffd184eba3-[NSView(NSInternal)_recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 1318
7 AppKit 0x00007fffd184f053-[NSView(NSInternal)_recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 2518
8 AppKit 0x00007fffd184e548 __46- [NSView(NSLayerKitGlue)drawLayer:inContext:] _ block_invoke + 267
9 AppKit 0x00007fffd184e071-[NSView(NSLayerKitGlue)_drawViewBackingLayer:inContext:drawingHandler:] + 1589
10 AppKit 0x00007fffd184da36-[NSView(NSLayerKitGlue)drawLayer:inContext:] + 80
11 AppKit 0x00007fffd19839ff-[_ NSBackingLayerContents drawLayer:inContext:] + 162
12 QuartzCore 0x00007fffd96a1e42-[CALayer drawInContext:] + 257
13 AppKit 0x00007fffd19834d8-[_ NSTiledLayer drawTile:inContext:] + 624
14 AppKit 0x00007fffd198320e-[_ NSTiledLayerContents drawLayer:inContext:] + 176
15 QuartzCore 0x00007fffd96a1e42-[CALayer drawInContext:] + 257
16 AppKit 0x00007fffd1983155-[NSTileLayer drawInContext:] + 169
17 QuartzCore 0x00007fffd9584a38 CABackingStoreUpdate_ + 3740
18 QuartzCore 0x00007fffd96a1a3c ___ZN2CA5Layer8display_Ev_block_invoke + 75
19 QuartzCore 0x00007fffd96a169d _ZN2CA5Layer8display_Ev + 1803
20 AppKit 0x00007fffd198306c-[NSTileLayer显示] + 119
21 QuartzCore 0x00007fffd9695546 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 572
22 QuartzCore 0x00007fffd9695671 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
23 QuartzCore 0x00007fffd968ae88 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 280
24 QuartzCore 0x00007fffd9581d55 _ZN2CA11Transaction6commitEv + 475
25 AppKit 0x00007fffd19701d9 __58-[_ NSScrollingConcurrentVBLMonitor _updateScrollAnimation] _block_invoke + 972
26 AppKit 0x00007fffd196aa3a-[_ NSScrollingConcurrentSharedData threadSafePropertyAccess:] + 44
27 AppKit 0x00007fffd196d127-[_ NSScrollingConcurrentVBLMonitor _updateScrollAnimation] + 672
28 AppKit 0x00007fffd196c84e-[_ NSScrollingConcurrentVBLMonitor _synchronizeForVBLSerialNumber:timestamp:updateDuration:] + 561
29 AppKit 0x00007fffd196c5ad __42-[_ NSScrollingConcurrentVBLMonitor简历] _block_invoke + 218
30 AppKit 0x00007fffd196c4ca __45- [NSScreen(NSScreenUpdate)addUpdateHandler:] _ block_invoke_2 + 212
31 libdispatch.dylib 0x000000010345ffcc _dispatch_client_callout + 8
32 libdispatch.dylib 0x0000000103476bca _dispatch_continuation_pop + 1025
33 libdispatch.dylib 0x000000010346c6bc _dispatch_source_latch_and_call + 195
34 libdispatch.dylib 0x0000000103462e15 _dispatch_source_invoke + 1106
35 libdispatch.dylib 0x00000001034768f0 _dispatch_continuation_pop + 295
36 libdispatch.dylib 0x000000010346deda _dispatch_async_redirect_invoke + 777
37 libdispatch.dylib 0x0000000103462247 _dispatch_root_queue_drain + 671
38 libdispatch.dylib 0x0000000103461f58 _dispatch_worker_thread3 + 114
39 libsystem_pthread.dylib 0x00000001034d78c2 _pthread_wqthread + 1299
40 libsystem_pthread.dylib 0x00000001034d739d start_wqthread + 13
)

最佳答案

NSView子类可以在OS X的最新版本中同时绘制。可以通过重写canDrawConcurrently并返回NO来关闭此行为。

您可能会发现,最好将 View 与模型再分离一点,然后再将要呈现的数据与CoreData管理的数据隔离开一些。将要呈现的数据提取到仅本地表示中,并让AppKit同时更新 View 。

https://developer.apple.com/reference/appkit/nsview/1483425-candrawconcurrently

关于multithreading - Mac OS会调用诸如drawRect : concurrently from different threads?之类的显示方法吗?访问数据模型时不是很危险吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40951789/

10-09 08:09