NSTimer 在 window 关闭后启动、停止和继续

NSTimer starts, stops, and continues after window closes

所以这就是人类逻辑中正在发生的事情(但不应该是)。

  1. 我的视图控制器加载
  2. 成功从 Parse 检索我的图像
  3. 将第一个检索到的图像设置为我的 UIImageView 图像
  4. 启动我的 5 秒计时器(我认为)
  5. 然后它什么都不做,只停留在第一张图片上
  6. 一旦我关闭 window(它由以前的视图控制器以模态方式呈现),我在控制台中看到我的 println() 输出并且我的计时器开始工作。

目标:在我的 UIImageView 中显示一个图像 5 秒左右,然后按顺序显示下一个图像 (imageArray)。

是我的计时器导致了这个功能暂停,还是与我的代码安排方式有关?非常感谢所有 suggestions/help,因为这是一个非常令人沮丧的问题。

这是 Swift 语言,但我可以阅读 Objective-C。

这是我的 class 代码:

//
//  ImageDisplayViewController.swift
//  
//
//  Created by on 5/3/15.
//
//

import Cocoa
import ParseOSX

class ImageDisplayViewController: NSViewController {


@IBOutlet weak var imageView: NSImageView!

var venue: String!
var imageArray = [(Int, NSImage)]()
var image: NSImage!
var timeToDisplay: Int = 0

var timer = NSTimer()

override func viewDidLoad() {
    super.viewDidLoad()

    venue = "Bees"
    loadImages()


}

var k: Int = 0

func presentNextImage() {
    if(k<imageArray.count) {
    imageView.image = imageArray[k].1
    timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: Selector("presentNextImage"), userInfo: nil, repeats: false)
        println(timer.timeInterval)
        //imageView.image = imageArray[k].1
        println("k is \(k)")
        k++
        println("Just set a new imageView.image")
    } else {
        println("K is n longer <imageArray.count")
    }
}



func loadImages() {
    var query = PFQuery(className:groupz)
    query.whereKeyExists("imageFile")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {
            println("Successfully retrieved \(objects!.count) objects.")
            // Do something with the found objects
            if let objects = objects as? [PFObject] {
                for object in objects {
                    let thumbNail = object["imageFile"] as! PFFile
                    self.image = NSImage(data: thumbNail.getData()!)
                    let time: AnyObject? = object["displayTime"]
                    self.timeToDisplay = time!.integerValue

                    let tempTuple = (self.timeToDisplay, self.image!)
                    self.imageArray.append(tempTuple)

                }
            }
            println("imageArray.count is: \(self.imageArray.count)")
            self.presentNextImage()
        } else {
            // Log details of the failure
            println("Error: \(error!) \(error!.userInfo!)")
        }
    }
}

}

将您的 NSTimer 声明为 weak。来自 NSTimer 上的 Apple docs

Note in particular that run loops maintain strong references to their timers, so you don’t have to maintain your own strong reference to a timer after you have added it to a run loop.

此外,您实际上不需要维护对计时器的引用,因为您没有在选择器参数中调用的方法之外调用 invalidate,在您的情况下,恰好是分配定时器的方法。

在您的情况下,保持对计时器的弱引用并使其无效以将其从 viewWillDisappear: 中的 运行 循环中移除。

Timer Programming Topics - Cocoa concept

我发现了问题。出于某种原因,将我的视图控制器(显示图像的那个)呈现为 Modal 导致计时器不 运行 或可能被添加到 NSRunLoop。我不太确定。但是,一旦我将 Segue 更改为 Show,我的计时器就开始正常工作。

感谢 Nikita 的帮助,实际上我从你对我问题的回答中学到了很多东西。