如何运行只在使用它的视图出现时才运行的异步线程?
我希望视图运行这个异步线程。但是,一旦视图消失,我希望该线程停止运行。最好的方法是什么?我不知道从哪里开始,可能会以错误的方式思考这个问题。然而,我所描述的是我希望它如何表现给用户。
答案 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)")
}
}
结果: