Swift dispatch_async 导致 EXC_BAD_ACCESS 错误
Swift dispatch_async results in EXC_BAD_ACCESS error
在我的 Swift 项目中,我试图在后台线程中处理一个 FIFO 队列(在这里我将其称为列表以避免混淆)。当我使用 dispatch_async 时,它会在仅执行列表的某些部分后导致 EXC_BAD_ACCESS 错误。
我已尽可能将代码简化为以下游乐场代码。
在 playground 中,当 main_thread 设置为 true 时,代码会处理列表中的所有 100 个项目。如果为假,则只会处理少数项目。如果代码在项目中,当 main_thread 为 false 时会出现 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()
您的主线程正在退出,而后台线程仍在 运行。主线程结束 -> 进程终止。
为 main 设置一些东西,以便在后台线程仍在运行时阻塞。例如,使用 dispatch_group_wait()
;连同 dispatch_group_enter()
和 dispatch_group_leave()
.
感谢 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
在我的 Swift 项目中,我试图在后台线程中处理一个 FIFO 队列(在这里我将其称为列表以避免混淆)。当我使用 dispatch_async 时,它会在仅执行列表的某些部分后导致 EXC_BAD_ACCESS 错误。 我已尽可能将代码简化为以下游乐场代码。 在 playground 中,当 main_thread 设置为 true 时,代码会处理列表中的所有 100 个项目。如果为假,则只会处理少数项目。如果代码在项目中,当 main_thread 为 false 时会出现 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()
您的主线程正在退出,而后台线程仍在 运行。主线程结束 -> 进程终止。
为 main 设置一些东西,以便在后台线程仍在运行时阻塞。例如,使用 dispatch_group_wait()
;连同 dispatch_group_enter()
和 dispatch_group_leave()
.
感谢 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