Cocoa:延迟一个方法调用,直到处理后续调用

时间:2014-05-29 18:03:37

标签: multithreading cocoa event-handling

我发现自己处于以下情况:我有一个带有活动单元格的NSTableView子类。当我点击用户界面上的其他地方时,委托方法(i)被触发,这反过来触发(ii)(我自己的方法)cocoa然后继续处理点击,导致最后两次调用。我对这个序列感到惊讶和失望,因为我假设鼠标点击将是第一个而不是最后一个处理过的事件。它也会导致我出现问题,因为manageState的理想实现依赖于mouseDown:中的一些处理,但当然manageState被调用mouseDown:时没有但已被执行。

他们是否可以延迟执行manageState直到mouseDown返回?例如,在manageState中,我会说停止!鼠标按下事件可能位于事件队列中。等到它完成,然后恢复。正如上一句所暗示的那样,这种方法也可能由鼠标按下以外的其他东西触发。在这种情况下,无需注意鼠标按下事件,处理可以正常继续。

MOUSE CLICK on NSTextView while NSTableView cell has focus...

+-------------------------+--------------------------------------------------------+
|Event                    |Triggered because                                       |
+=========================+========================================================+
|controlTextDidEndEditing:|The mouse click ends the editing session                |
|                         |of the active cell in my table view                     |
+-------------------------+--------------------------------------------------------+
|manageState              |This method is a selector that belongs to a notification|
|                         |that is fired from within controlTextDidEndEditing:     |
+-------------------------+--------------------------------------------------------+
|becomeFirstResponder     |I clicked on the NSTextView instance                    |
+-------------------------+--------------------------------------------------------+
|mouseDown:               |Finally, the click that started it all is processed     |
+-------------------------+--------------------------------------------------------+

1 个答案:

答案 0 :(得分:0)

我为自己想出了这个。我担心我不得不拼凑一个基于线程的解决方案,但是更多的文档搜索提出了NSEvent类方法addLocalMonitorForEventsMatchingMask:handler

当我的应用程序启动时,我调用此方法,定义关联的块,并告诉'方法我想要注意哪些事件。然后,只要检测到其中一个事件,该块就会运行。至关重要的是,这种情况发生在事件引发的任何处理开始之前。在块中,您有机会停止事件,或继续处理,您还可以访问事件本身。回到我的问题,这意味着我有效地在表格的顶部插入了一行。这是完美的,因为它允许我在任何后续事件执行之前对事件采取行动。

[NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask 
                                      handler:^NSEvent *(NSEvent *event) {
    // whenever an event of type NSLeftMouseDownMask is detected, this code
    // will run before any other event processing

    // do some processing, then...

    return event; // or nil, if you want to block the event
}];