【问题标题】:Collection was mutated while being enumerated crash with NSTableView, NSArrayController and NSThread集合在被 NSTableView、NSArrayController 和 NSThread 枚举崩溃时发生突变
【发布时间】:2010-10-13 14:59:09
【问题描述】:

在我的小型核心数据应用程序中,我有一些在实体模式下与 NSArrayController 控制器绑定的 NSTableView 视图。

当我尝试在后台线程中将大量数据导入我的表时,在成功添加了一些导入(从几十个到数百个项目)后,我的日志崩溃了:

严重的应用程序错误。在核心数据更改处理期间捕获到异常:*** 集合在枚举时发生了变异。NSHashTable (%@) { [5] (entity: Word; id: 0x1001dd4b0 ; data: { ....... 这里是实体描述.... } ....

...和堆栈跟踪:

#0  0x7fff83e0e2fa in mach_msg_trap
#1  0x7fff83e0e96d in mach_msg
#2  0x7fff8816c614 in _CGSSynchronizeWindowBackingStore
#3  0x7fff88152169 in _CGSLockWindow
#4  0x7fff88158cff in CGSDeviceLock
#5  0x7fff81ecae43 in ripd_Lock
#6  0x7fff81eca746 in ripl_BltShape
#7  0x7fff81ec7d86 in ripc_Render
#8  0x7fff81ec5317 in ripc_DrawRects
#9  0x7fff88158641 in CGContextFillRects
#10 0x7fff8818ee1a in CGContextFillRect
#11 0x7fff86e712f8 in NSRectFillUsingOperation
#12 0x7fff86f2152e in NSDrawWindowBackground
#13 0x7fff86ea16c2 in -[NSThemeFrame drawWindowBackgroundRect:]
#14 0x7fff86e6eb9a in -[NSFrameView drawThemeContentFill:inView:]
#15 0x7fff86e68aa5 in -[NSThemeFrame drawRect:]
#16 0x7fff86e68131 in -[NSView _drawRect:clip:]
#17 0x7fff86e65907 in -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:]
#18 0x7fff86e64ee8 in -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:]
#19 0x7fff86e6179a in -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
#20 0x7fff86ddaff6 in -[NSView displayIfNeeded]
#21 0x7fff86dd5ea2 in _handleWindowNeedsDisplay
#22 0x7fff80099a2d in __NSFireTimer
#23 0x7fff815aa678 in __CFRunLoopRun
#24 0x7fff815a884f in CFRunLoopRunSpecific
#25 0x7fff82c3991a in RunCurrentEventLoopInMode
#26 0x7fff82c3971f in ReceiveNextEventCommon
#27 0x7fff82c395d8 in BlockUntilNextEventMatchingListInMode
#28 0x7fff86dab29e in _DPSNextEvent
#29 0x7fff86daabed in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
#30 0x7fff86d708d3 in -[NSApplication run]
#31 0x7fff86d695f8 in NSApplicationMain

假设更新表存在问题(枚举不是线程安全的),我尝试通过在导入开始使用之前禁用控制器和表来解决此问题:

[wordsController setEditable:NO];
[wordsController setAutomaticallyPreparesContent:NO];
[wordsTable setEnabled:NO];

但这无济于事。在导入期间,我仍然看到新实体被添加到故事中,直到崩溃。

任何人都知道在后台处理期间禁用 NSArrayController 跟踪更改的技巧是什么?还是这里有其他问题?

非常感谢您的任何提示。

【问题讨论】:

    标签: multithreading cocoa crash enumeration nsarraycontroller


    【解决方案1】:

    您是否在导入或 UI 更新中使用快速枚举(“for (id object in collection) {...}”)?如果是这样,请注意您不能在枚举期间修改集合(添加或删除)。

    这也可能是插入到您的数组控制器正在刷新的同一上下文中的结果。在这种情况下,您需要一个独立于“显示结果”上下文的“导入”上下文。在导入期间,您将合并每个 x 个导入对象的上下文,从而刷新“显示结果”上下文。

    【讨论】:

    • 我不在导入代码中使用交互,但你对第二件事是正确的:我使用相同的托管对象上下文进行导入和显示。我将尝试为后台线程使用另一个托管对象上下文。
    【解决方案2】:

    通过禁用 TableView,我成功避免了该错误:

    [table setHidden:YES]
    

    在开始向我的 ArrayController 添加项目之前。

    【讨论】:

    • 您可能误认为这是一种解决方案,因为此错误取决于线程速度。支持您的答案,因为它不值得 -1。
    猜你喜欢
    • 2013-01-21
    • 2014-07-04
    • 1970-01-01
    • 2012-07-30
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多