iOS Swift中Selector函数未触发问题咨询
排查iOS通知Selector未触发的问题
Hey,我来帮你捋捋这个问题,我之前做Swift通知的时候也踩过类似的坑,咱们一步步排查:
1. 最容易踩的坑:通知名称不匹配
你在第一个控制器里定义的通知名称是Notification.Name("hideLiveBtn"),但在第二个相机控制器添加观察者时,是不是用了完全一致的名称?
比如有没有可能在第二个控制器里重新定义notificationhide时拼写错误?比如写成了"hideliveBtn"(小写L),或者大小写不一致?建议把通知名称定义成全局扩展常量,彻底避免这类问题:
// 全局扩展,放在任意.swift文件里都可以 extension Notification.Name { static let hideLiveBtn = Notification.Name("hideLiveBtn") }
之后发送和接收都用.hideLiveBtn,就不会出现拼写差错了。
2. Selector签名不匹配
你的Selector函数写的是:
@objc func hideliveBtn(notification : NSNotification...)
这里用了可变参数...,但通知中心只会传递单个NSNotification对象,可变参数的签名和通知中心的期望不匹配,导致找不到对应的方法。
修正成普通的单参数签名就好:
@objc func hideliveBtn(notification: NSNotification) { // 你的逻辑代码 print("通知成功触发!") }
如果用下划线省略外部参数名,对应的Selector也要同步修改:
@objc func hideliveBtn(_ notification: NSNotification) { ... } // 对应的Selector是 #selector(hideliveBtn(_:))
3. 观察者未被正确添加(控制器状态问题)
你是在第二个控制器的viewDidLoad里添加观察者的,要确认:
- 这个控制器的
viewDidLoad确实被调用了吗?可以加个打印验证:override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(...) print("相机控制器观察者已添加") } - 控制器是不是已经被释放了?如果控制器已经
deinit,那肯定收不到通知。可以在deinit里加打印确认:deinit { print("相机控制器已销毁") // iOS9+通知中心会自动移除观察者,但手动移除更稳妥 NotificationCenter.default.removeObserver(self) }
4. 通知发送时机太早
如果第一个控制器的发送按钮动作在第二个控制器初始化并添加观察者之前就触发了,那通知已经发出去了,后面才添加的观察者自然收不到。
比如你是不是在App启动时就触发了通知,但相机控制器还没被push/present出来?可以调整发送时机,确保是在相机控制器加载完成之后再发送通知。
修正后的完整示例代码
全局通知名称定义
extension Notification.Name { static let hideLiveBtn = Notification.Name("hideLiveBtn") }
第一个控制器发送通知
@IBAction func sendNotificationBtnTapped(_ sender: UIButton) { NotificationCenter.default.post(name: .hideLiveBtn, object: nil) print("通知已发送") }
第二个相机控制器接收通知
class CameraViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 添加观察者 NotificationCenter.default.addObserver(self, selector: #selector(hideliveBtn(notification:)), name: .hideLiveBtn, object: nil) print("相机控制器观察者已添加") } @objc func hideliveBtn(notification: NSNotification) { print("通知触发,执行隐藏按钮逻辑") // 这里写你的隐藏按钮代码 } deinit { NotificationCenter.default.removeObserver(self) print("相机控制器已销毁,移除观察者") } }
按照上面的步骤排查,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者PvDev
相关产品推荐
相关产品推荐

