Timer.scheduledTimer抛出“无法识别的选择器发送到实例”

时间:2017-12-10 01:50:28

标签: swift nstimer unrecognized-selector

我正在安排一个我想推送通知的计时器。需要注意的是,我的#selector是一个单例的函数,如下面的代码所示。但是,当发出计时器信号,并且调用#selector(NotificationManager.instance.pushNotification(timer :))时,我会得到下面概述的异常转储。当我采用相同的功能并将其放置在视图控制器中时,一切都在世界上并且没有问题。有什么想法吗?

2017-12-09 20:33:47.439754-0500 Accumoo[3404:2488862] -[MyApp.MainViewController pushNotificationWithTimer:]: unrecognized selector sent to instance 0x107077800
2017-12-09 20:33:47.440181-0500 Accumoo[3404:2488862] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyApp.MainViewController pushNotificationWithTimer:]: unrecognized selector sent to instance 0x107077800'
*** First throw call stack:
(0x184c89d04 0x183ed8528 0x184c971c8 0x18e47f110 0x184c8f6b0 0x184b7501c 0x18567bd24 0x184c3292c 0x184c32650 0x184c31e50 0x184c2fa38 0x184b4ffb8 0x1869e7f84 0x18e1242e8 0x104b3f624 0x18467256c)
libc++abi.dylib: terminating with uncaught exception of type NSException 

这是代码......

在我的视图控制器中......

// Send user a local notification if they have the app running in the background...
let userInfo = ["title" : "Title", "body" : "Body", "timeIntervalSeconds" : Double(0), "repeats" : false] as [String : Any]
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)

在我的NotificationManager类中......

class NotificationManager /*: PushNotificationProtocol*/ {
   static let instance = NotificationManager()

   private init() {
   }

   @objc public func pushNotification(timer:Timer) {
      guard let userInfo = timer.userInfo as? Dictionary<String, Any> else { return }

      let title = (userInfo["title"] as? String).valueOrDefault()
      let body = (userInfo["body"] as? String).valueOrDefault()
      let timeIntervalSeconds = (userInfo["timeIntervalSeconds"] as? Double) ?? 0
      let repeats = (userInfo["repeats"] as? Bool) ?? false

      self.pushNotification(sender: nil, title: title, body: body, timeIntervalSeconds: timeIntervalSeconds, repeats: repeats)
   }

   public func pushNotification(sender:Any?, title:String, body:String) {
      self.pushNotification(sender: sender, title: title, body: body, timeIntervalSeconds: 0, repeats: false)
   }

   public func pushNotification(sender:Any?, title:String, body:String, timeIntervalSeconds:Double, repeats:Bool) {
      // Center
      let center = UNUserNotificationCenter.current()

      // Content...
      let content = UNMutableNotificationContent()
      content.title = title
      content.body = body
      content.sound = UNNotificationSound.default()

      // Trigger
      let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeIntervalSeconds, repeats: repeats)

      // Push it...
      // Does this need to be unique?
      let identifier = "NotificationManagerIdentification"
      let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
      center.add(request, withCompletionHandler: { (error) in
         if let error = error {
            print("Something went wrong: \(error)")
         }
      })
   }
}

** *更新* **

事实证明,Timer.scheduleTimer的调用需要像这样编码(参见@ maddy的答案):

// Send user a local notification if they have the app running in the background...
let userInfo = ["title" : "Title", "body" : "Body", "timeIntervalSeconds" : Double(10), "repeats" : false] as [String : Any]
Timer.scheduledTimer(timeInterval: 0.5, target: NotificationManager.instance, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)

1 个答案:

答案 0 :(得分:1)

您将错误的目标传递给计时器。

变化:

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)

为:

Timer.scheduledTimer(timeInterval: 0.5, target: NotificationManager.instance, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)

请记住,目标需要实际实现要指定的选择器的类的实例。您正在传递self,它是视图控制器。