2016-07-25 7 views
-1

Я использую NSTimer для отправки сообщения на интервале. Вот код:Отправка сообщения о назначении NSTimer в другой класс; извлечение его параметра userInfo

{ 
    // .... 
    var params : [String] = [] 
    params.append(conversion) 
    params.append(message) 
    let timer = NSTimer(fireDate: date, interval: 60, target: self, selector: Selector("importTextMessage.sendMessage:"), userInfo: params, repeats: true) 

    NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes) 
    // ... 
} 


func sendMessage(params: [String]){ ...} 

Я также попытался изменить на 2.2 синтаксис Swift:

let timer = NSTimer(fireDate: date, interval: 60, target: self, selector: #selector(importTextMessage.sendMessage(_:)), userInfo: params, repeats: true) 

, но это ничего не меняет.

Из всех других вопросов, связанных с «Непризнанным селектором, отправленным экземпляру», ответ «включает в себя двоеточие в Селекторе, чтобы он знал, чтобы захватить аргументы из UserInfo», но я включил это и не могу выяснить, что не так.

Что Примечание:

Параметры для функции и параметры, передаваемые через NSTimer USERINFO DO совпасть. Это оба массива строк.

Если это что-то значит, код не работает при вызове sendMessage. На самом деле это не делает его sendMessage.

Я получаю странное предупреждение о том, что «строка буквальное не является допустимым селектором Objective-C»

Я попытался изменить мой код для моего SendMessage взять таймер в качестве аргумента, как 1 пользователь предложил: func sendMessage(timer: NSTimer){ но который по-прежнему дает ту же ошибку.

Благодарим за оказанную помощь заранее, я ценю это.

EDIT: здесь есть функция, которая запускает таймер: // Сохраняет все данные @IBAction Func saveText (отправитель: AnyObject) { вара телефона: Двойная вара активен: Int частота вара: Double вара сообщение: String дата вара: NSDate

phone = Double(currentNumber)! 
    active = 1 
    message = myTextView.text 
    date = myDatePicker.date 

    switch self.frequency.selectedRowInComponent(0) { 
     case 0: 
      frequency = 1 
     case 1: 
      frequency = 3 
     case 2: 
      frequency = 6 
     case 3: 
      frequency = 24 
     case 4: 
      frequency = 168 
     case 5: 
      frequency = 744 
     default: 
      frequency = 8760 
    } 

    importTextMessage.seedMessage(phone, active: active, frequency: frequency, message: message, date: date) 

    print(date) 
    let conversion : String = "+1" + String(Int(phone)) 


    //importTextMessage.sendMessage("Ryan", to: conversion, message: message) 
    var params : [String] = [] 
    params.append(conversion) 
    params.append(message) 
    //importTextMessage.sendMessage(params) 

    let timer = NSTimer(fireDate: date, interval: 60, target: self, selector: #selector(importTextMessage.sendMessage(_:)), userInfo: params, repeats: true) 
    //   
    NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes) 

} 

EDIT: Точные mssg ошибки:

непризнанного селектора послал к экземпляру 0x7ffe6b915460 2016-07- 25 13: 26: 09,092 Беспокоить Ваш Кейт [53524: 9000621] *** Нагрузочного приложение из-за неперехваченное исключение 'NSInvalidArgumentException', причина: «- [Harass_Your_Kate.AddMessageViewController SendMessage]: непризнанный селектор направлен например 0x7ffe6b915460

ответ

0

В API из NSTimer является таким, что приемник (целевая функция) должна принимать один и только один параметр, тип NSTimer.

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/#//apple_ref/occ/clm/NSTimer/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

сообщение отправить на цель, когда таймер сработает.

Селектор должен иметь следующую подпись: timerFireMethod: (включая двоеточие, указывающее, что метод принимает аргумент). Таймер проходит себя в качестве аргумента, таким образом, метод будет принять следующую закономерность:

  • (пустоты) timerFireMethod: (NSTimer *) таймер

В Swift подписью обязательно быть

правка: обновляется, чтобы соответствовать код в точности

Примечание: Swift 2.2 Синтаксис

class TextMessageViewController: UIViewController { 
    var importTextMessage: AddMessageViewController // init'd somehow 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // ... 

     // Note how selector matches *the name of the class* 
     // As I understand it now, the sendMessage method 
     // is declared in the AddMessageViewController class, 
     // and importTextMessage is the name of the instance of that class. 
     // And we're in a different class now, TextMessageViewController, 
     // so using `self` does not make sense here. 
     let timer = NSTimer(fireDate: date, interval: 60, target: importTextMessage, 
      selector: #selector(AddMessageViewController.sendMessage(_:)), userInfo: params, repeats: true) 
     NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes) 
    } 
} 


class AddMessageViewController: UIViewController { 
    // func must not be private 
    func sendMessage(timer: NSTimer) { 
     // And now for example 
     print("params: \(timer.userInfo)") 
    } 
} 

Насколько словарю USERINFO, то есть свойство объекта таймера, а не параметр самой целевой функции.

ВТОРОЙ ошибка состоит в том, что синтаксис селектора не в состоянии использовать имя класса, как заявлено, а не имя некоторой переменной экземпляра, который имеет ссылку на этот экземпляр класса. Включите больше контекста в свой вопрос, чтобы он быстрее решался!

THIRD Ошибка в том, что вы используете неправильное имя класса. Если вы используете self, то имя класса в селекторе должно соответствовать имени текущего класса. Поскольку вы действительно хотите, чтобы сообщение перешло в другой класс, вы должны использовать , чтобы вместо этого ссылаться на ссылку. См. Обновленный код.

Я думаю, что вы все еще не полностью понимаете ссылки на объекты, их типы и то, как они должны совпадать, и как self - это просто ссылка на контекстный объект.

+0

Так как это правильно, это, вероятно, не должно быть опущено, но мне любопытно, почему. – BaseZen

+0

Я не ответил на ваш ответ, но это не помогает. У меня есть точная вещь, которую вы и другой ответчик имеете, но это не изменяет ошибку. Он по-прежнему говорит, что приложение Terminating из-за неперехваченного исключения «NSInvalidArgumentException», непризнанный селектор, отправленный в экземпляр 0x13601f910 ' – Ryan

+0

Если его Swift3 добавить подчеркивание перед первым параметром вашего метода –

1

С doc:

таймер передает себя в качестве аргумента

так таймер ожидать другого типа аргумента, NSTimer. Попробуйте этот код:

override func viewDidLoad() {   
    super.viewDidLoad() 

    var params : [String] = [] 
    params.append(conversion) 
    params.append(message) 
    let timer = NSTimer(fireDate: date, interval: 60, target: self, selector: #selector(sendMessage(_:)), userInfo: params, repeats: true) 
    NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes) 
} 

func sendMessage(sender: NSTimer) { 
    print(sender.userInfo as? [String]) 
} 

Этот код прекрасно работает в моем стандартном контроллере представления

+0

Когда я реализую этот код, он ничего не меняет. Перед выполнением sendMessage возникает ошибка. Когда я просматриваю отладчик, мои параметры верны: p params ([String]) $ R0 = 2 значения { [0] = "+1 ..... 52" [1] = "Эй, " } – Ryan

+0

После выхода из функции он дает ошибку. После перехода через NSRunLoop он выполняет некоторые инструкции по сборке и затем выдает ошибку. ошибка NSInvalidArgumentException и непризнанный селектор @Shadow Of – Ryan

+0

@Ryan Я пока не вижу никаких шансов на ошибки. Пожалуйста, предоставьте еще несколько кодов. Ошибка может быть в 'date' getter (заменить его на' NSDate() ') или somwhere else –

 Смежные вопросы

  • Нет связанных вопросов^_^