2016-08-28 154 views
1

在我的Swift項目中,我試圖在後臺線程中處理一個FIFO隊列(我將在這裏稱之爲列表以避免混淆)。當我使用dispatch_async時,只有部分列表執行後,會導致EXC_BAD_ACCESS錯誤。 我已儘可能簡化代碼到以下操場代碼中。 在操場中,當main_thread設置爲true時,代碼將處理列表中的所有100個項目。如果它是錯誤的,只有少數項目得到處理。如果代碼在項目中,則在main_thread爲false時發生EXC_BAD_ACCESS。顯然,我也試過指定一個串行隊列,但這似乎沒有幫助。 我在想什麼? 謝謝。Swift dispatch_async導致EXC_BAD_ACCESS錯誤

import UIKit 

let main_thread = false 
let serial_queue = true 

class main_class { 
    var this_list = list_class() 


    func run(){ 
     for i in 1...100 { 
      this_list.add_to_list(String(i)) 
     } 

     if main_thread { 
      this_list.process_list() 
     } else { 
      if serial_queue { 
       let my_serial_queue = dispatch_queue_create("msq", DISPATCH_QUEUE_SERIAL) 
       dispatch_async(my_serial_queue){()->Void in 
        self.this_list.process_list() 
       } 
      } else { 
       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {() ->Void in 
        self.this_list.process_list() 
       }) 
      } 

     } 
    } 
} 

class list_class { 
    var my_list: [String] = [] 

    func add_to_list(this: String){ 
     my_list.append(this) 
    } 

    func process_list(){ 
     if my_list.count > 0 { 
      print("removing " + my_list[0]) 
      remove_from_list(my_list[0]) 
     } 
    } 

    func remove_from_list(this: String){ 
     let found = my_list.indexOf(this) 
     if found != nil { 
      my_list.removeAtIndex(found!) 
      process_list() 
     } 
    } 
} 

var blah = main_class() 
blah.run() 

回答

1

當後臺線程仍在運行時,您的主線程正在退出。主線程結束 - >進程終止。

在後臺線程仍在運行時設置一些主要阻止的內容。例如,使用dispatch_group_wait();以及dispatch_group_enter()dispatch_group_leave()

+0

我明明在這裏失去了一些非常核心理念:(在把dispatch_async的點有那麼主線程沒有被封鎖,我現在非常困惑 – Matt

+0

@Matt:把'dispatch_async'放在那裏,主線程沒有被異步工作負載阻塞*主線程可以自由地做其他事情,就像等待I/O一樣,如果你在主線程上沒有別的事情,那麼'dispatch_async'就沒有意義了。 –

+0

在一個「普通」應用程序中,主要忙着做其他事情,或者等待用戶輸入;除了結束處理用戶輸入對於及時處理是至關重要的,因此您不希望主要做長時間的工作。將它移動到後臺線程是正確的。但是在你的示例中,沒有用戶輸入來處理main,因此模型不相關。 –

0

感謝Graham Perks的回答,我需要dispatch_group_wait - 我結束了這段代碼的工作。我沒有預計需要2異步調用:(XCPlayground只是在操場上必需的。

import UIKit 
import XCPlayground 

var GlobalMainQueue: dispatch_queue_t { 
    return dispatch_get_main_queue() 
} 
var GlobalBackgroundQueue: dispatch_queue_t { 
    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) 
} 

class main_class { 
    var this_list = list_class() 
    var done = "NO" 
    func run(){ 
     for i in 1...100 { 
      this_list.add_to_list(String(i)) 
     } 

     dispatch_async(GlobalBackgroundQueue){ 
      let ds_group = dispatch_group_create() 

      dispatch_group_enter(ds_group) 
      dispatch_async(GlobalMainQueue){ 
       self.this_list.process_list() 
       dispatch_group_leave(ds_group) 
      } 

      dispatch_group_wait(ds_group, DISPATCH_TIME_FOREVER) 
      dispatch_async(GlobalMainQueue){ 
       self.done = "YES" 
      } 
     } 

    } 
} 

class list_class { 
    var my_list: [String] = [] 

    func add_to_list(this: String){ 
     my_list.append(this) 
    } 

    func process_list(){ 
     if my_list.count > 0 { 
      print("removing " + my_list[0]) 
      remove_from_list(my_list[0]) 
     } 
    } 

    func remove_from_list(this: String){ 
     let found = my_list.indexOf(this) 
     if found != nil { 
      my_list.removeAtIndex(found!) 
      process_list() 
     } 
    } 
} 

var blah = main_class() 
blah.run() 
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true 
+0

這不屬於答案。 –

+0

這是爲什麼?是否因爲我的問題的具體措辭是「我缺少什麼或不瞭解什麼」?而我的回答只是擴大了Graham Perks提供的暗示。我並不是想要變得困難,我只是不明白爲什麼你認爲它不屬於它。是否應該在格雷厄姆的回答下面發表評論?我不認爲代碼可以/應該發表評論。謝謝你幫助一個noob海報。 – Matt

相關問題