1

这是:

[self showInWindow:window];

delay这段代码调用了什么:

[self performSelector:@selector(showInWindow:)
           withObject:window
           afterDelay:delay];

还是我误解了方法?

编辑:我遇到的问题是该方法showInWindow在延迟后被调用,但行为类似于[self showInWindow:nil]. 有什么建议吗?

4

2 回答 2

2

是的,这就是所谓的。(当然是在延迟之后。)

该文档并没有真正解释“执行选择器”的含义,但它的含义正是您所怀疑的。

使用类型方法和直接发送消息之间有一个小的区别performSelector:withObject::它们只有在对象实际上是一个对象(即id,一个指向 Objective C 对象的指针)时才起作用。但window显然是一个对象。

(严格来说,这并不完全正确。如果您传递与 a 大小相同id或更小的东西,它通常会起作用。在某些情况下它不会。在某些情况下它会起作用,但是是非法的。在某些情况下情况下,它会起作用并且是合法的,但Apple强烈建议不要这样做。没有任何情况下这是一个好主意 - 所以不要学习特定规则,只是假设它永远不会起作用。提出这个问题的唯一原因是它使用了早在 NeXT 时代就成为 Objective C 中的常见做法,因此您可能偶尔仍会在今天的其他人中看到它。)

有关该performSelector:系列的更多信息,请参阅NSObject Protocol Reference和 SO 问题Using -performSelector: vs. just calling the method。(有关afterDelay:变体的具体信息,请参阅上面链接的文档。)

从后来的编辑到问题:

我遇到的问题是该方法showInWindow在延迟后被调用,但行为类似于[self showInWindow:nil]. 有什么建议吗?

首先,它以什么方式“表现得像”参数为零?参数实际上是 nil 吗?(只需将其记录在showInWindow:实现中;如果您尚未覆盖基本实现,只需添加一个覆盖记录并调用基本实现。)

其次,如果它实际上是 nil,那么在你发送的时候它是 nilperformSelector:withObject:afterDelay:吗?如果是这样,显然发送选择器时它仍然为零。另外,请确保window确实是一种id而不是其他类型。(请注意,如果您有成员、属性、全局变量和/或本地变量共享名称window,则可能会混淆您指的是哪一个。这是问题的常见来源。)

如果你安排它时它实际上不是 nil,但它到达时它是 nil,有几种方法可能发生,但它们都比这两种情况更不可能,而且调试起来更棘手,所以让我们先排除它们.

于 2012-09-21T18:07:40.813 回答
0

是的,这就是它的作用......尽管请记住,执行时间可能比延迟时间长。该方法基本上在当前线程的运行循环中设置了一个NSTimer,因此如果您的线程忙于执行繁重的工作并且运行循环的返回时间比您延迟返回的时间长,那么您的方法将稍后执行。

于 2012-09-21T18:08:20.983 回答