2016-07-25 1 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構文に変更しようとしている:ここではコードです

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

が、それは何も変わりません。

"インスタンスに送信された未知のセレクタ"について投稿されたすべての質問から、「セレクタにコロンを挿入してUserInfoから引数を取得することがわかっています」が含まれています。何が間違っているのか理解する。

何を注意する:

関数のパラメータとNSTimerのUserInfo DOマッチアップを介して渡されたパラメータ。どちらも文字列の配列です。

何かを意味する場合、sendMessageが呼び出されている間、コードは失敗しています。それは実際にメッセージを送信することはありません。

私は1人のユーザーが示唆されているように、引数としてタイマーを取るために私のsendMessageのための私のコードを変更しようとした

「リテラル文字列が有効なObjective-Cのセレクタではありません」という奇妙な警告取得しています:func sendMessage(timer: NSTimer){をしかし、それでも同じエラーが発生します。

事前にお手数をおかけしていただきありがとうございます。

編集:ここでタイマーを実行機能は次のとおりです。{ VAR電話:アクティブダブル VAR:のInt VAR周波数:ダブル VAR://はsaveText(ANYOBJECT送信者)funcをデータ @IBActionのすべてを保存メッセージ:文字列 VAR日: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

NSTimerのAPIは、受信機(ターゲット機能)タイプ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 *)タイマースウィフト署名する必要があり

be

編集:あなたのコードに正確に一致するように更新されました。

注:スウィフト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)") 
    } 
} 

は限り、あなたのユーザ情報辞書として、それは、タイマーオブジェクトではなく、ターゲット関数自体へのパラメータのプロパティです。

SECOND間違いは、セレクタの構文は宣言されたクラスの名前を使用するように失敗していることを、そのクラスのインスタンスへの参照を持ついくつかのインスタンス変数の名前はありません。あなたの質問にもっと多くの文脈を含めると、より速く解決されます!

THIRD間違ったクラス名を使用しています。 selfを使用する場合、セレクタのクラス名は、現在のクラスの名前と一致する必要があります。メッセージを実際に別のクラスに移動する場合は、代わりにの参照を使用する必要があります。更新されたコードをご覧ください。

私はあなたがまだオブジェクト参照とオブジェクトの型とそれらがどのように一致しなければならないか、完全に把握していないと思います。selfはコンテキストオブジェクトへの参照に過ぎません。

+0

これは正しいので、おそらくdownvotedするべきではありませんが、なぜ私は興味があります。 – BaseZen

+0

私はあなたの答えをdownvoteしませんでしたが、コードを助けるものではありません。私はあなたと他の回答者が持っている正確なことを持っていますが、それはエラーを変更しません。まだ未知の例外 '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が実行される前に、エラーがスローされます。私がデバッガを通過するとき、私のパラメータは正しいです: ([String])$ R0 = 2の値{ [0] = "+1 ..... 52"[1] = " " } – Ryan

+0

関数を終了すると、エラーが発生します。 NSRunLoopをステップ実行した後、いくつかのアセンブリ命令をステップ実行し、エラーをスローします。エラーはNSInvalidArgumentExceptionであり、認識できないセレクタ@Shadow Of – Ryan

+0

@ Ryan今のところエラーは発生しません。いくつかのコードを追加してください。エラーは 'date' getter(NSDate()'で置き換えてください)またはsomhere elseにある可能性があります –

関連する問題