簡體   English   中英

Swift NSTimer無法識別的選擇器發送到實例timerFireMethod

[英]Swift NSTimer unrecognized selector sent to instance timerFireMethod

我在Swift for iOS 9.2中編寫了一些計時器代碼。我通過xcode下載了最新的iOS 9.2文檔

(void)timerFireMethod:(NSTimer *)timer

但這不起作用。 如果我使用這樣的簽名

func timerFire(timer : NSTimer?)
func timerFire(timer : NSTimer)

然后我得到了錯誤

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DSP1.PlayManager timerFire]: unrecognized selector sent to instance

我唯一可以上班的是這樣的通話簽名

func play(sound : String)
{
    bsound = theLM?.getPlayer(sound)
    bsound?.delegate = self
    bsound?.play()
    stimer = NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire"), userInfo: self, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}

// Docs say signature should be (void)timerFireMethod:(NSTimer *)timer.      Docs are wrong
func timerFire()
{
    print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}

但這與通過XCode下載的最新iOS 9.2文檔說的應該不相符。

  • 我這樣做了嗎?
  • 為什么新加載的iOS 9.2文檔似乎有錯誤的簽名?
  • 有什么其他人閱讀Swift iOS編程的准確文檔?

(編輯為更清楚,文檔中列出的回調簽名無法在運行時工作)

回答:

在對NSTimer的調用中,如果作為Selector傳入的函數名稱有一個尾隨冒號,則表示您希望將計時器作為參數傳遞給您的方法。 沒有冒號意味着您不希望將計時器作為參數傳遞。

NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire"), userInfo: self, repeats: true)
func timerFire()

要么

NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire:"), userInfo: self, repeats: true)
func timerFire(timer : NSTimer)

NSTimer的文檔提到了這個選擇器參數,但還遠未明確。 “選擇器應具有以下簽名:timerFireMethod :(包括冒號以指示該方法接受參數)。”

你的代碼似乎還可以。 計時器的選擇器沒有預定義的簽名,只要你的班級中有一個具有該名稱的方法,你就可以隨心所欲地使用它。

func play(sound : String) {
    // ....
    stimer = NSTimer(timeInterval: 1.0, target: self, selector: "methodToRunOnTimerTick", userInfo: self, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}

func methodToRunOnTimerTick() {
    print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}

還有一件事需要記住,您決定使用的方法也可以在調用時將定時器作為參數接收。 這種情況看起來像這樣:

func play(sound : String) {
    // ....
    stimer = NSTimer(timeInterval: 1.0, target: self, selector: "methodToRunOnTimerTick:", userInfo: self, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}

func methodToRunOnTimerTick(timer: NSTimer) {
    print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}

所以你以正確的方式實現計時器,該方法不需要特殊的簽名。 如果您需要更多幫助,請告訴我。 祝你的項目好運!

你犯了一個簡單而又常見的錯誤。

您的方法簽名應該是:

func timerFire(timer: NSTimer) {}

你的計時器設置應該是:

NSTimer(timeInterval: 1.0, target: self, selector: "timerFire:", userInfo: nil, repeats: true)

錯誤是您在選擇器名稱中缺少冒號。 timerFiretimerFire:不同timerFire: 跳過冒號,它會尋找這樣的方法:

func timerFire() {}

沒有NSTimer參數。 最好包括參數,然后包括冒號,以便您可以確認您獲得的計時器是您期望的計時器。

通知也是如此。 如果您使用的是通知中心,請在方法中包含冒號和通知對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM