Mac OS是否同时从不同的线程调用drawRect等显示方法?访问数据模型时不是很危险吗?

And*_*ann 3 macos cocoa multithreading nsview

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

ERROR: Assertion failed: [NSThread isMainThread]:  (ZS_AppDelegate.m:1287)
(
    0   tomedo_kunden                       0x00000001008af46a -[ZS_AppDelegate loggedInUser] + 554
    1   tomedo_kunden                       0x00000001016feca7 +[Nutzer loggedInUser] + 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 display] + 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 resume]_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
)

bbu*_*bum 6

NSView子类可以在最新版本的OS X中同时绘制.可以通过覆盖canDrawConcurrently和返回来关闭此行为NO.

您可能会发现最好将视图与模型分开一点,并将要渲染的数据与CoreData托管数据隔离一点; 将要呈现的数据拉入仅本地表示,并让AppKit同时更新视图.

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