NSTimer无效无效

时间:2016-10-04 17:41:08

标签: ios swift nstimer

我无法停止为执行二次操作而创建的计时器NSTimer

我已阅读并尝试了各种可能的Web指南,但没有一个工作,即使控制器被销毁,计时器也会继续运行。以下是有问题的代码:

/* Copy banner in a temp array and change order to random value */
private func getBanners(){
    let realm = try! Realm()
    let banners = self.synchronizer.getAllBanners()?.sorted("ordine")
    if let banners = banners {
        for banner in banners {
            let random = Double.random(0.0, 1.0)
            let currentOrderValue = banner.ordine
            self.banners.append(banner)
            do {
                try realm.write({
                    self.banners.last!.ordine = currentOrderValue + random
                })
            } catch let error as NSError {
                print(error)
            }
        }
    }

}

/*Update index of banner to show */
func updateIndex(timer : NSTimer) {
    if self.index+1 < self.banners.count {
        for banner in self.banners{
            print(banner.name + " \(banner.ordine)")
        }
        self.index+=1
    } else {
        self.index = 0
    }
    self.setImageBanner()
}

/* Set image of banner to show*/
private func setImageBanner() {
    if self.banners.count > 0 {
        self.bannerImage.hidden = false
        let banner = self.banners[self.index]
        let file = banner.images[0]
        self.synchronizer.loadImageURL(file.link, imageView: self.bannerImage)
    } else {
        self.bannerImage.hidden = true
    }
}

/* Start Timer */
func startTimerForBanners() {
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        self.getBanners()
    })
    self.timer = NSTimer(timeInterval: 5, target: self, selector: #selector(self.updateIndex(_:)), userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(self.timer!, forMode: NSRunLoopCommonModes)
}

/* Open link on banner click */
func openLink(sender : UITapGestureRecognizer){
    if self.index >= 0 && self.index < self.banners.count {
        let banner = self.banners[self.index]
        print(banner.name)
        self.synchronizer.openLink(banner.url)
    }
}

func trialLesson(sender : UITapGestureRecognizer){
    performSegueWithIdentifier("trial_lesson_segue", sender: nil)

}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if let timer = self.timer {
        timer.invalidate()
    }
}

2 个答案:

答案 0 :(得分:0)

您需要在启动新计时器之前使计时器无效。目前我相信你可能会多次调用“startTimerForBanners”,因此启动了很多计时器线程。一种方法是逐个启动所有计时器,或者在启动新计时器之前使其无效,如此

/* Start Timer */
func startTimerForBanners() {
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        self.getBanners()
    })
**self.timer.invalidate()**
    self.timer = NSTimer(timeInterval: 5, target: self, selector: #selector(self.updateIndex(_:)), userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(self.timer!, forMode: NSRunLoopCommonModes)
}

答案 1 :(得分:0)

您确定您的控制器是否已真正解除分配? 关于NSTimer,您应该始终注意一件事:它保留了它的目标。

我建议:

  1. viewWillAppear
  2. 中启动计时器
  3. viewDidDisappear
  4. 中无效并将计时器设置为nil
  5. 还尝试用此(Swift 3)替换您的开始计时器代码:
  6. timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.updateIndex(_:)), userInfo: nil, repeats: true)