2016-10-04 281 views
1

我無法停止定時器NSTimer創建執行輔助操作。NSTimer無效無效

我已閱讀並嘗試過各種可能的Web指南,但沒有任何工作,並且計時器即使在Controller被銷燬時也會繼續運行。下面是有問題的代碼:

/* 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() 
    } 
} 
+0

從哪裏打電話'startTimerForBanners'? –

+0

你試過timer = nil嗎? – kocakmstf

+1

@kocakmstf'timer = nil'不會停止計時器。 –

回答

0

您需要在啓動新計時器之前使計時器無效。目前我相信你可能會多次調用「startTimerForBanners」,所以很多定時器線程已經啓動。一種方法是通過一個invlidate都定時器一個或開始新的一個這樣的

/* 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) 
} 
+0

'計時器'是可選的,所以你會'定時器?.invalidate( )'。 – Rob

+1

是的計時器是一個可選類型。我在銷燬控制器之前使計時器無效,但不起作用... – Marco

0

你確定你的控制器是真正釋放之前剛剛失效? 有一點你應該始終注意NSTimer:它保留了它的目標。

我會建議:

  1. viewWillAppear
  2. 的Invalidate啓動定時器,並設置定時器,以零在viewDidDisappear
  3. 也可以嘗試與此更換你的計時器開始代碼(SWIFT 3):

timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.updateIndex(_:)), userInfo: nil, repeats: true)