找到你要的答案

Q:cancellation of NSOperationQueue does not work in swift

Q:取消nsoperationqueue不工作迅速

I'm trying to cancel all the threads in NSOperationQueue using swift but it does not work.

I'm trying start and stop the thread using NSOperationQueue when user clicks button. Also if time taken to execute myFunc is more than 20 seconds then timer will stop it and display alert.

Below is my code :

import UIKit

class ViewController: UIViewController {

    var myTimer = NSTimer()
    var isSet = true
    var icount = 0

    let operationQueue = NSOperationQueue()


    override func viewDidLoad() {
        super.viewDidLoad()

    }

    var th123:NSThread!


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func myFunc()
    {
        println("Thread start..")
    }


    @IBAction func btnClickEvent(sender: AnyObject) {

       if(isSet == false)
        {
            isSet = true
            myTimer.invalidate()

            // th123.cancel()
            operationQueue.cancelAllOperations()

            btnClick.setTitle("Start", forState: UIControlState.Normal)
            //NSThread.exit()
        }
        else if (isSet == true)
        {
            isSet = false

            myTimer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkTime"), userInfo: nil, repeats: true)
            NSLog("Timer started..")
            btnClick.setTitle("Stop", forState: UIControlState.Normal)

            Other()

        }

    }

    func myfunc1()
    {

    }

    func checkTime()
    {
        icount = icount + 10

        if( icount > 18 ) {

            isSet = false

            operationQueue.cancelAllOperations()

            let alertController = UIAlertController(title: "iOScreator", message:
                "Opps Some Error occurred !!", preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))

            self.presentViewController(alertController, animated: true, completion: nil)
            myTimer.invalidate()
            btnClick.setTitle("Start", forState: UIControlState.Normal)
        }

    }



 func Other() {

customOperation.completionBlock = {

    MyObject.myFunc()
}


var workerBlockOperation:NSBlockOperation = NSBlockOperation.self.init(
    block: {
        MyObject.myFunc()
    }
)


    operationQueue.addOperation(customOperation)
    operationQueue.addOperation(workerBlockOperation)


}


    @IBOutlet weak var lblstatus: UILabel!
    @IBOutlet weak var btnClick: UIButton!
}

MyObject.swift file

import Foundation

class MyObject {

  class func myFunc()
    {
        NSLog(" myFunc called ")

        for i in 1...1000000 {
            println(i)
        }
    }

}

I would prefer to go with NSThread but i'm don't know how to forcefully stop/kill the NSthread.

I added below code but still not able to cancel task

我想取消nsoperationqueue使用SWIFT的所有线程但它不工作。

我试着启动和停止线程使用nsoperationqueue当用户点击按钮。如果采取执行MyFunc时间超过20秒,然后计时器将停止并显示报警。

下面是我的代码:

import UIKit

class ViewController: UIViewController {

    var myTimer = NSTimer()
    var isSet = true
    var icount = 0

    let operationQueue = NSOperationQueue()


    override func viewDidLoad() {
        super.viewDidLoad()

    }

    var th123:NSThread!


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func myFunc()
    {
        println("Thread start..")
    }


    @IBAction func btnClickEvent(sender: AnyObject) {

       if(isSet == false)
        {
            isSet = true
            myTimer.invalidate()

            // th123.cancel()
            operationQueue.cancelAllOperations()

            btnClick.setTitle("Start", forState: UIControlState.Normal)
            //NSThread.exit()
        }
        else if (isSet == true)
        {
            isSet = false

            myTimer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkTime"), userInfo: nil, repeats: true)
            NSLog("Timer started..")
            btnClick.setTitle("Stop", forState: UIControlState.Normal)

            Other()

        }

    }

    func myfunc1()
    {

    }

    func checkTime()
    {
        icount = icount + 10

        if( icount > 18 ) {

            isSet = false

            operationQueue.cancelAllOperations()

            let alertController = UIAlertController(title: "iOScreator", message:
                "Opps Some Error occurred !!", preferredStyle: UIAlertControllerStyle.Alert)
            alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))

            self.presentViewController(alertController, animated: true, completion: nil)
            myTimer.invalidate()
            btnClick.setTitle("Start", forState: UIControlState.Normal)
        }

    }



 func Other() {

customOperation.completionBlock = {

    MyObject.myFunc()
}


var workerBlockOperation:NSBlockOperation = NSBlockOperation.self.init(
    block: {
        MyObject.myFunc()
    }
)


    operationQueue.addOperation(customOperation)
    operationQueue.addOperation(workerBlockOperation)


}


    @IBOutlet weak var lblstatus: UILabel!
    @IBOutlet weak var btnClick: UIButton!
}

myobject.swift文件

进口的基础

class MyObject {

  class func myFunc()
    {
        NSLog(" myFunc called ")

        for i in 1...1000000 {
            println(i)
        }
    }

}

我宁愿去nsthread但我不知道如何强制停止/杀nsthread。

我添加了下面的代码,但仍然不能取消任务

answer1: 回答1:

Cancelling NSOperation just sets it isCanceled property to true, it will not stop the execution of that operation, rest its up to you how you handle this, usually you will check for isCancelled before execution the code inside operation, something like this.

if (!op.isCancelled){
//its means operation (op) is not cancelled
// execute cod
}

Update: If you are using NSBLock operation then it should be something like this

customOpeation =  NSBlockOperation ()
        customOpeation .addExecutionBlock {
            if !customOpeation.cancelled
            {
                // operation is not cancelled
                // so you can execute code
                myFunc()
            }
        }

If you want to get check if operation is cancelled inside myFunc method, then you will need to have operation reference otherwise it will execute, and if you have reference you can do something like this.

class MyObject {

  class func myFunc()
    {
        NSLog(" myFunc called ")

        for i in 1...1000000 {
            if operation.cancelled
            { //break loop as operation is cancelled
            }
            println(i)
        }
    }

}

How you will send reference of an operation to myFunc will depend how your app is architect.

Recommended Subclass NSOperation and add functionality inside that than you can easily check if operation is cancelled or not and this one is the recommended way

 class Opeation : NSOperation
    {
        override func main() {
            if !cancelled
            {
                myFunc()
            }
        }
        func myFunc()
        {
            for i in 1...1000000 {
                if cancelled
                {
                    break
                }
                println(i)
            }
        }
    }

After this just create an object of Operation and add it to opeartionQueue

只是将它取消的NSOperation iscanceled属性设置为true,它不会停止,其余操作的执行,取决于你如何处理这个,你通常会检查被执行之前的代码在运行,像这样的东西。

if (!op.isCancelled){
//its means operation (op) is not cancelled
// execute cod
}

Update: If you are using NSBLock operation then it should be something like this

customOpeation =  NSBlockOperation ()
        customOpeation .addExecutionBlock {
            if !customOpeation.cancelled
            {
                // operation is not cancelled
                // so you can execute code
                myFunc()
            }
        }

如果你想取消操作在MyFunc方法得到检查,那么你将需要运行参考否则会执行,如果你有参考,你可以做这样的事情。

class MyObject {

  class func myFunc()
    {
        NSLog(" myFunc called ")

        for i in 1...1000000 {
            if operation.cancelled
            { //break loop as operation is cancelled
            }
            println(i)
        }
    }

}

你将如何把一个操作参考MyFunc将依赖于你的应用程序架构师。

Recommended Subclass NSOperation and add functionality inside that than you can easily check if operation is cancelled or not and this one is the recommended way

 class Opeation : NSOperation
    {
        override func main() {
            if !cancelled
            {
                myFunc()
            }
        }
        func myFunc()
        {
            for i in 1...1000000 {
                if cancelled
                {
                    break
                }
                println(i)
            }
        }
    }

这只是创建操作对象并将其添加到opeartionqueue后

ios  iphone  multithreading  swift  nsoperationqueue