Область применения NSTimer()

Моя проблема: NSTimer(), объявленный в одной функции, влияет на другую.

Я делаю простую ролевую игру, которая позволяет двум игрокам сражаться друг с другом. В игре есть текстовое поле, в котором отображаются односекундные сообщения, например, "Первый игрок атакует" и т. Д. После завершения игры в текстовом поле предполагается напечатать победителя и оставить сообщение в текстовом поле. Для решения первой части (показать сообщение, через одну секунду показать пустую строку) я сделал следующий код:

    func printEmpty() {
    textToDisplayLabel.text = ""
}
    func announcer(player: Character) {
    var timer = NSTimer()
    textToDisplayLabel.text = "\(player.name) attacks"
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "printEmpty", userInfo: nil, repeats: false)

}

Для решения второй части (показать информацию о победителе и оставить ее в текстовом поле) я использовал:

    func hideAfterAPlayerHasWon(winner: Character) {
    leftPlayerAttackButton.hidden = true
    rightPlayerAttackButton.hidden = true
    leftPlayerHpLabel.hidden = true
    rightPlayerHpLabel.hidden = true
    leftPlayerNameLabel.hidden = true
    rightPlayerNameLabel.hidden = true

    if winner.side == Character.playerSide.left {
        soldierMain.hidden = true
        let centerXConst = NSLayoutConstraint(item: orcMain, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 1)
        let centerYConst = NSLayoutConstraint(item: orcMain, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 1)
        self.view.addConstraint(centerXConst)
        self.view.addConstraint(centerYConst)
        textToDisplayLabel.text = "\(leftPlayer.name) has won"

    } else {
        orcMain.hidden = true
        let centerXConst = NSLayoutConstraint(item: soldierMain, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 1)
        let centerYConst = NSLayoutConstraint(item: soldierMain, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1, constant: 1)
        self.view.addConstraint(centerXConst)
        self.view.addConstraint(centerYConst)
        textToDisplayLabel.text = "\(rightPlayer.name) has won"
    }

}

Проблема в том, что при запуске игры отображается информация о действиях, например, "атаках игроков" и т. Д., И они скрываются через одну секунду, как я хочу, но информация о победителе ведет себя так же, как о действиях, даже если бы они думали таймер был объявлен только в функции извещателя. Таким образом, у меня возник вопрос: какова область применения NSTimer () и как мне решить эту проблему?

РЕДАКТИРОВАТЬ: Вот функция, где вызывается диктор (а также hideAfter...)

@IBAction func onLeftPlayerAttackPressed(sender: UIButton) {
    if leftPlayer.type == Character.charType.orc {
        playOrcSlash()
    }
    if leftPlayer.type == Character.charType.soldier {
        playSoldierSlash()
    }
    announcer(leftPlayer)
    updateHp(leftPlayer, defender: rightPlayer)
    disableButton(leftPlayerAttackButton)
    if !(rightPlayer.isAlive) {
        hideAfterAPlayerHasWon(leftPlayer)
    }
}

2 ответа

какова сфера применения NSTimer()

У него нет "объема". Как только вы запланировали это, он принадлежит NSRunLoop, который владеет им и отвечает за его запуск. Если это неповторяющийся таймер, он исчезает после срабатывания.

Это не имеет ничего общего с вашей проблемой. У вас есть элементарная логическая ошибка:

  1. onLeftPlayerAttackPressed устанавливает таймер (announcer(leftPlayer)) и звонки hideAfterAPlayerHasWon,

  2. затем hideAfterAPlayerHasWon ставит "игрок выиграл" на этикетке.

  3. Затем таймер срабатывает и снова очищает этикетку!

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

Задержка вызова вашей функции hideAfterAPlayerHasWon на одну или две секунды, так что вы уверены, что ваш таймер уже сработал.

if !(rightPlayer.isAlive) {
  let yourDelayTime = (Int64(NSEC_PER_SEC) * NUMBER_SECOND_DELAY)
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, yourDelayTime), dispatch_get_main_queue(), { () -> Void in
   self.hideAfterAPlayerHasWon(leftPlayer)
  })  
}
Другие вопросы по тегам