为什么无法识别的选择器发送到实例?
Why Unrecognized selector sent to instance?
我正在尝试制作一个方便的绑定键盘到 uiview 函数。我无法解决这个错误
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Twitter.LoginVC handleKeyboard:]: unrecognized selector sent to instance 0x7ffbf142e970'
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(self.handleKeyboard(_:))) // **CRASHES HERE**
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
这是我的通知服务:
class NotificationService {
static let instance = NotificationService()
func addKeyboardObservers(onVC vc: UIViewController, handleKeyboardSelector: Selector) {
NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
}
编辑:
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
编辑 2:
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(handleKeyboard(_:)))
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
在 vc 的 viewDidLoad() 中:
KeyboardService().bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)
您正在尝试将选择器发送至 vc
;但它是一个 UIViewController
实际上并没有名为 handleKeyboard(_:)
的方法。您应该将您的注册方式更改为:
func addKeyboardObservers(_ observer: Any, handleKeyboardSelector: Selector) {
NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
然后当你使用它时,你会做:
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))
如您所见,您现在要触发 self
上的选择器,因为它实际上是 self
具有该方法。
作为一般规则:选择器被发送到一个实例,因此该实例必须具有所选方法。
如果您真的想将选择器发送到 viewController
实例,您可以创建一个 extension
将方法添加到每个 UIViewController
extension UIViewController {
@objc func handleKeyboard(_ notification: NSNotification) {
// do your stuff here
}
}
然后,在注册时执行:
NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(vc.handleKeyboard(_:))) // notice the vc.handleKeyboard instead of self.handleKeyboard
编辑
尝试在视图控制器中保留键盘服务:
let keyboardService = KeyboardService()
override func viewDidLoad() {
super.viewDidLoad()
keyboardService.bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)
}
我正在尝试制作一个方便的绑定键盘到 uiview 函数。我无法解决这个错误
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Twitter.LoginVC handleKeyboard:]: unrecognized selector sent to instance 0x7ffbf142e970'
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(self.handleKeyboard(_:))) // **CRASHES HERE**
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
这是我的通知服务:
class NotificationService {
static let instance = NotificationService()
func addKeyboardObservers(onVC vc: UIViewController, handleKeyboardSelector: Selector) {
NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
}
编辑:
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
编辑 2:
class KeyboardService {
var constraint: NSLayoutConstraint!
var vc: UIViewController!
func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
constraint = bottomConstraint
self.vc = vc
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(handleKeyboard(_:)))
}
@objc func handleKeyboard(_ notification: NSNotification) {
NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}
在 vc 的 viewDidLoad() 中:
KeyboardService().bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)
您正在尝试将选择器发送至 vc
;但它是一个 UIViewController
实际上并没有名为 handleKeyboard(_:)
的方法。您应该将您的注册方式更改为:
func addKeyboardObservers(_ observer: Any, handleKeyboardSelector: Selector) {
NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
然后当你使用它时,你会做:
NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))
如您所见,您现在要触发 self
上的选择器,因为它实际上是 self
具有该方法。
作为一般规则:选择器被发送到一个实例,因此该实例必须具有所选方法。
如果您真的想将选择器发送到 viewController
实例,您可以创建一个 extension
将方法添加到每个 UIViewController
extension UIViewController {
@objc func handleKeyboard(_ notification: NSNotification) {
// do your stuff here
}
}
然后,在注册时执行:
NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(vc.handleKeyboard(_:))) // notice the vc.handleKeyboard instead of self.handleKeyboard
编辑 尝试在视图控制器中保留键盘服务:
let keyboardService = KeyboardService()
override func viewDidLoad() {
super.viewDidLoad()
keyboardService.bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)
}