2015-08-15 91 views
1

我想取消NSOperationQueue使用swift中的所有線程,但它不起作用。取消NSOperationQueue不能在迅速工作

我想在用戶單擊按鈕時啓動並停止使用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。

我加了下面的代碼,但仍無法取消任務

+1

所有取消'NSOperation'確實將'cancelled'設置爲'true'。您的操作應該定期檢查它是否被取消,並在發生這種情況時停止任何工作。你沒有這樣做。 –

+1

我不確定你到底想要完成什麼,但我從來沒有見過用這種方式混合使用「NSOperation」和「NSThread」。我不知道你的操作爲什麼在其外使用引用('self.th123'),但這通常是糟糕的設計。你的實際目標是什麼? –

+0

@ Aaron Brager - 我的目標是當用戶點擊按鈕啓動一個執行某些操作的線程,並且當單擊相同的按鈕時,即我的線程應該強制停止。同時這樣做,我的用戶界面不應該被阻止。因此使用NSThread NSOperation。 – cybergeeeek

回答

2

取消NSOperation只是將它isCanceled屬性爲true,也不會停止操作的執行,休息,其取決於你如何處理這個問題,通常你會在執行代碼之前檢查isCancelled是否在運行,像這樣。

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

更新: 如果您正在使用NSBLock操作,它應該是這樣的

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

如果你想檢查是否operationcancelledmyFunc方法,那麼您將需要有操作參考,否則它會執行,如果你有參考,你可以做這樣的事情。

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將取決於您的應用程序是架構師。

推薦 子類NSOperation和添加功能裏面是不是你可以很容易地檢查是否操作被取消或沒有,這一次是推薦的方式

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

在此之後,就是創建一個Operation一個對象,並添加它到opeartionQueue

+0

與addOperationwithBlock如果我們創建操作..我無法取消它。 – cybergeeeek

+0

是的,你不能這樣做,這就是你通過獲取簡短的語法而失去的東西,改爲使用NSBlock操作並在init中傳遞一個塊 https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSBlockOperation_class /#// apple_ref/occ/clm/NSBlockOperation/blockOperationWithBlock: –

+0

我添加了NSBlockOperation代碼,但仍無法做到這一點。 – cybergeeeek