Swift dispatch\u async导致EXC\u BAD\u访问错误

Swift dispatch\u async导致EXC\u BAD\u访问错误,swift,exc-bad-access,dispatch-async,Swift,Exc Bad Access,Dispatch Async,在我的Swift项目中,我试图在后台线程中处理FIFO队列(我在这里称之为列表以避免混淆)。当我使用dispatch_async时,仅在执行了部分列表之后,就会导致EXC_BAD_访问错误。 我已经尽可能地将代码简化为以下代码。 在操场上,当main_thread设置为true时,代码将处理列表中的所有100项。如果为false,则只处理少数项目。如果代码在项目中,当主线程为false时,会发生EXC_BAD_访问。显然,我也尝试过指定一个串行队列,但这似乎没有帮助。 我遗漏了什么或不理解什么?

在我的Swift项目中,我试图在后台线程中处理FIFO队列(我在这里称之为列表以避免混淆)。当我使用dispatch_async时,仅在执行了部分列表之后,就会导致EXC_BAD_访问错误。 我已经尽可能地将代码简化为以下代码。 在操场上,当main_thread设置为true时,代码将处理列表中的所有100项。如果为false,则只处理少数项目。如果代码在项目中,当主线程为false时,会发生EXC_BAD_访问。显然,我也尝试过指定一个串行队列,但这似乎没有帮助。 我遗漏了什么或不理解什么? 谢谢


主线程正在退出,而后台线程仍在运行。主线程结束->进程终止


在后台线程仍在运行时设置要阻止的主线程。例如,使用
dispatch_group_wait()
;由于格雷厄姆·珀克斯的回答,我需要派遣小组等待,因此,除了
派遣小组进入()
派遣小组离开()。我没想到会需要2个异步调用:(XCPlayde只在游乐场中需要

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

很明显,我在这里遗漏了一些相当核心的概念:(将dispatch\u async放入其中的目的是使主线程没有被阻塞。我现在非常困惑。@马特:将
dispatch\u async
放入其中的目的是使主线程没有被异步工作负载阻塞。然后主线程可以自由地做其他事情,比如等待I/O。如果您没有其他事情在主线程上执行,那么
dispatch\u async
是没有意义的app main将忙于做其他事情,或等待用户输入;除了结束之外,其他任何事情都可以。处理用户输入是至关重要的,必须及时处理;因此,您不希望main做长时间的工作。您将其移动到后台线程是正确的。但在这里的示例中,main没有用户输入可处理,因此该模型不可靠这不是一个答案。为什么?是因为我问题的具体措辞是“我缺少什么或不理解什么?”?我的回答只是对Graham Perks提供的提示进行了扩展?我并不是故意刁难你,我只是不明白你为什么认为它不属于你?它应该放在Graham回答下面的注释中吗?我不认为代码可以/应该放在注释中。谢谢你帮助一张noob海报。
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