2016-10-04 23 views
1

Ich kann den Timer nicht stoppen NSTimer erstellt, um sekundäre Operationen durchzuführen.NSTimer invalidate funktioniert nicht

Ich habe alle möglichen Web-Führer gelesen und ausprobiert, aber keiner hat funktioniert und der Timer läuft weiter, auch wenn der Controller zerstört ist. Unten ist der betreffende Code:

/* 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

Von wo Sie anrufen 'startTimerForBanners'? –

+0

hast du versucht timer = nil? – kocakmstf

+1

@kocakmstf 'timer = nil' stoppt den Timer nicht. –

Antwort

0

Sie müssen den Timer vor dem Start eines neuen Timers ungültig machen. Momentan glaube ich, dass Sie "startTimerForBanners" viele Male aufrufen, so viele Timer-Thread wurde initiiert. Ein Ansatz ist es, alle Timer eins nach dem anderen invlidate oder ungültig machen, bevor neue Start-ähnliche

/* 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

Die 'timer' ist optional, also würdest du' timer? .invalidate () '. – Rob

+1

Ja, der Timer ist ein optionaler Typ. Ich mache den Timer ungültig, bevor ich den Controller zerstöre, aber es funktioniert nicht ... – Marco

0

Sind Sie sicher, dass Ihr Controller wirklich ausgeplant? Es gibt eine Sache, die Sie immer über NSTimer wissen sollten: es behält sein Ziel bei.

Ich würde vorschlagen, zu:

    Ihre Timer in viewWillAppear
  1. Invalidate und Zeitschaltuhr auf Null starten
  2. in viewDidDisappear
  3. Versuchen Sie auch Ihren Start Timer-Code mit diesem ersetzen (Swift 3):

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