【问题标题】:UIApplication's sendAction() works even if target(forAction:…) is nil即使 target(forAction:…) 为 nil,UIApplication 的 sendAction() 也可以工作
【发布时间】:2019-07-24 00:45:35
【问题描述】:

当点击子视图 (imageSlideshow) 时调用此代码:

        imageSlideshow.didTap = { [weak self] in
        guard UIApplication.shared.sendAction(#selector(ImageCarouselViewResponder.didTapImageCarousel(sender:)), to: nil, from: self, for: nil) else {
            assertionFailure("No target for ImageCarouselViewResponder.didTapImageCarousel(sender:)")
            return
        }
        …

这可以按预期工作,正如您从以下调试输出中看到的那样:

(lldb) po UIApplication.shared.sendAction(#selector(ImageCarouselViewResponder.didTapImageCarousel(sender:)), to: nil, from: self, for: nil) 
true

但是,当我尝试使用相同的选择器请求目标时,它是 nil:

(lldb) po UIApplication.shared.target(forAction: #selector(ImageCarouselViewResponder.didTapImageCarousel(sender:)), withSender: self)
nil

此外,我添加了一个扩展来遍历响应者树以找到第一个响应者,在这种情况下它返回 nil

如果没有第一响应者,sendAction(…) 如何工作?

【问题讨论】:

  • 你在Cocoa Event Handling Guide看到这个页面了吗?
  • 所以文件说系统将事件下面的项目作为第一响应者,但如果是这样的话,我仍然不明白为什么target(forAction:)返回nil

标签: ios uikit first-responder uiresponder


【解决方案1】:

调用target(forAction:) 只会将请求传递到响应者链来自该响应者,但只有after the application in the responder chain is the application delegate。除非在这两个中的任何一个中实现此方法,否则在应用程序实例上调用 target(forAction:) 将返回 nil

使用nil 目标调用sendAction(_:to:from:for:) 是可行的,因为它将消息发送到第一响应者,后者将其向上传递到响应者链直到它被处理。

【讨论】:

  • 我不确定他的视图层次结构中是否有第一响应者。 sendAction(_:to:from:for:) 方法之所以有效,是因为他设置了一个发送者对象。此方法,将尝试找出第一响应者。如果找到了第一响应者,那么将向它发送一个动作。如果第一响应者不存在,则将尝试从发送者对象开始发送操作。
猜你喜欢
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多