Swift Serial Dispatch Block仅在委托后完成

时间:2015-04-03 22:28:39

标签: ios swift asynchronous

这是一个难以解释的问题。我正在创建一个串行队列来处理我的应用程序中的一些工作。想象一下,我做了这样的事情:

dispatch_async(myQueue, { () -> Void in
            self.SendSMS();
            });

dispatch_async(myQueue, { () -> Void in
            self.SendEmail();
            });

现在我想做的是只在委托(SendSMS委托)完成其工作后调用self.SendEmail。

有一种简单的方法吗?

非常感谢

3 个答案:

答案 0 :(得分:2)

假设SendSMS是一个异步方法,我建议改变SendSMS以完成处理程序的关闭:

// define property to hold closure

var smsCompletionHandler: (()->())?

// when you initiate the process, squirrel away the completion handler

func sendSMSWithCompletion(completion: (()->())?) {
    smsCompletionHandler = completion

    // initiate SMS
}

// when the SMS delegate method is called, call that completion closure

func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
    // do whatever you want when done

    // finally, call completion handler and then release it

    smsCompletionHandler?()
    smsCompletionHandler = nil
}

因此,您可以这样称呼它,将sendEmail放在sendSMS的完成闭包中:

self.sendSMSWithCompletion() {
    self.sendEmail()
}

我不知道你的sendSMSsendEmail正在做什么,但是如果你正在调用MessageUI框架,你通常会在主队列上执行此操作。但是如果你真的需要在你的专用队列上进行上述操作,那么随时可以在那里发送它。但希望这说明了这个概念:(a)供应完成处理程序关闭; (b)保存,以便您的代表可以打电话给它; (c)当调用委托时,使用该封闭属性然后重置它。

答案 1 :(得分:0)

一种方法,它的作用是:

dispatch_async(myQueue, { () -> Void in
        self.SendEmail();
        });

在代表的最后。但我不知道这是否是唯一的方法。

干杯

答案 2 :(得分:-1)

是的,您可以在接下来的步骤中执行此操作:

// create tasks group handle
let taskGroup = dispatch_group_create()
let mainQueue = dispatch_get_main_queue()

// write your blocks in needed order
dispatch_group_async(taskGroup, mainQueue) { [weak self] in
    // execute your code
    // don't forget to use self with optional, i.e.: self!.property or function
    self!.SendSMS()
}

dispatch_group_async(taskGroup, mainQueue) { [weak self] in
    self!.SendEmail()
}

// and of course you need to catch completion of this task group
dispatch_group_notify(taskGroup, mainQueue) {
    println("All work is done, milord!")
}

UPD。上面的解决方案是关于没有订单的异步执行,因为命名,并且两个中的一个可以比声明的顺序更早完成。您需要使用依赖关系作为持续执行的解决方案。我在谈论多线程的排序,而不是完成闭包或执行器模式。 请注意,执行此操作的案例不止一个。其中之一 - 下面:

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue) {
    dispatch_sync(queue) {[weak self] in
        self?.SendSMS()
    }

    dispatch_sync(queue) {[weak self] in
        self?.SendEmail()

        // here you need to call your completion of success function in main thread
    }
}

请注意,函数中的代码必须存在于同一队列中,并对服务器请求使用同步方法。但这是另一个故事;)