如何运行只在使用它的视图出现时才运行的异步线程?

时间:2016-09-10 01:41:37

标签: swift multithreading asynchronous

如何运行只在使用它的视图出现时才运行的异步线程?

我希望视图运行这个异步线程。但是,一旦视图消失,我希望该线程停止运行。最好的方法是什么?我不知道从哪里开始,可能会以错误的方式思考这个问题。然而,我所描述的是我希望它如何表现给用户。

2 个答案:

答案 0 :(得分:0)

您可以使用NSOperation来实现您的目标,NSOperation和NSOperationQueue建立在GCD之上。作为一般规则,Apple建议使用最高级别的抽象,然后在测量显示需要时降低到较低级别。

例如,您希望在加载视图时异步下载图像,并在视图消失时取消任务。首先创建一个ImageDownloader对象子类到NSOperation。请注意,我们检查操作是否被取消两次,这是因为NSOperation有3个状态:isReady -> isExecuting -> isFinish,当操作开始执行时,它不会自动取消,我们需要自己完成。< / p>

class ImageDownloader: NSOperation {
    //1
    var photoRecord: NSURL = NSURL(string: "fortest")!

    //2
    init(photoRecord: NSURL) {
        self.photoRecord = photoRecord
    }

    //3
    override func main() {
        //4
        if self.cancelled {
            return
        }
        //5
        let imageData = NSData(contentsOfURL:self.photoRecord)

        //6
        if self.cancelled {
            return
        }

    }
}

然后您可以使用它:downloader.cancel()downloader.start()。请注意,我们需要检查完成块中是否取消了操作。

import UIKit

class ViewController: UIViewController {
    let downloder = ImageDownloader(photoRecord: NSURL(string: "test")!)

    override func viewDidLoad() {
        super.viewDidLoad()

        downloder.completionBlock = {
            if self.downloder.cancelled {
                return
            }
            print("image downloaded")
        }
        //Start the task when the view is loaded
        downloder.start()    
    }

    override func viewWillDisappear(animated: Bool) {
        //Cancel the task when the view will disappear
        downloder.cancel()

    }

}

答案 1 :(得分:0)

显示 DetailViewController 后, asyncOperation方法将异步执行。

注意:目前 asyncOperation方法每秒执行一次,所以如果您只希望调用该方法一次,则必须更改重复属性 false

class DetailViewController: UIViewController {
  // timer that will execute
  // asynchronously an operation
  var timer: NSTimer!

  // counter used in the async operation.
  var counter = 0

  // when view is about to appear
  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    // setting up the timer
    timer = NSTimer.scheduledTimerWithTimeInterval(
      1.0,
      target: self,
      selector: #selector(asyncOperation),
      userInfo: nil,
      repeats: true //set up false if you don't want the operation repeats its execution.
    )
  }

  // when view is about to disappear
  override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    // stopping the timer
    timer.invalidate()
  }

  // async operation that will
  // be executed
  func asyncOperation() {
    counter += 1
    print("counter: \(counter)")
  }
}

来源:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/

结果: