【问题标题】:How does NSUndoManager.groupsByEvent determine the current run loop pass?NSUndoManager.groupsByEvent 如何判断当前运行循环是否通过?
【发布时间】:2017-05-20 09:43:00
【问题描述】:

我想了解/复制NSUndoManger 的“按运行循环传递/循环分组”功能:

NSUndoManager 可以在同一运行循环循环中多次调用registerUndo() 时将多个调用组合成一个“撤消”操作。这是由NSUndoManager.groupsByEvent 确定的,默认设置为true

所以是这样的:

// User clicks button... (causes a new run loop event)
undoManager.registerUndo(...) // #1
undoManager.registerUndo(...) // #2

...产生一个撤消组,单击编辑 → 撤消 会同时还原这两项更改。

NSUndoManager 可以通过某种方式判断两个对registerUndo() 的调用是否在同一个运行循环周期中。这是如何工作的?

我的用例:

我有在用户与 UI 交互(例如单击按钮)后发送属性更改通知的代码。作为用户操作的结果,可以有一个或多个事件。我想将它们分组并在当前运行循环结束时只更新一次 UI。

【问题讨论】:

  • “默认情况下,撤消组在事件循环开始时自动开始”。 NSUndoManager 打电话给beginUndoGrouping 如果你没有。你能多谈谈你的用例吗? “作为用户操作的结果的一个或多个事件”是什么意思?你如何更新 UI,reloadDatasetNeedsDisplayInRect,画点什么?
  • 感谢您的意见。我不想详细说明我如何或为什么更新 UI。首先,我很想了解幕后发生的事情。本质上,我想在一个运行循环周期内批量调用一个方法。另一个例子是去抖动调用,并且只考虑每个运行循环周期的最后一个调用(由单个用户交互触发)。

标签: cocoa foundation nsrunloop cfrunloop


【解决方案1】:

NSUndoManager 通常在运行循环期间自动创建撤消组。第一次被要求在运行循环中记录撤消操作时,它会创建一个新组。然后,在循环结束时,它关闭组。

来源:Undo Operations and Groups

NSUndoManagerNSRunLoop 属于同一框架,因此NSRunLoop 可能会向NSUndoManager 发出信号以关闭一个组。你不知道也不应该想知道。

【讨论】:

  • “然后,在循环结束时,它会关闭组。”但是它究竟是如何知道运行循环何时结束的呢?我确实想知道,因为我很好奇,而且我可能会在此过程中学到一些有用的东西。
  • -[NSUndoManager endUndoGrouping]+[NSUndoManager(NSPrivate) _endTopLevelGroupings] 中被调用,在-[NSApplication run] 中被调用。
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 2014-09-28
  • 2015-02-07
  • 2011-03-13
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多