GCD和回调 - 并发问题 [英] GCD and callbacks - concurrency issue

查看:152
本文介绍了GCD和回调 - 并发问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注册了一个回调处理程序,用于侦听iOS通讯簿中的更改。由于一些奇怪的原因(已经提交了一个错误),当应用程序从后台返回时,有时可以多次调用此回调。我希望我的回调处理程序只运行一次逻辑,即使在多次调用回调的情况下也是如此。这是我注册回调的方式:

I have a callback handler registered that listens to changes in the iOS Address Book. Due to some strange reason (for which a bug has been filed), this callback can sometimes be called more than once when the app returns from the background. I want my callback handler to run it's logic only once, even in cases the callback is called multiple times. This is how I register the callback:

ABAddressBookRegisterExternalChangeCallback(address_book, adressBookChanged, self);

这是我构建回调处理程序以利用GCD来处理这个问题的方法。不幸的是,它不起作用,并且GCD不会阻止内部逻辑被调用两次...

This is how I structured my callback handler to take advantage of GCD to handle this. Unfortunately, it's not working, and GCD doesn't prevent the internal logic to be called twice...

void adressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void 
                       *context) 
{ 
    NSLog(@"** IN addressBookChanged callback!");

    ABAddressBookUnregisterExternalChangeCallback (ab, adressBookChanged, context);

    __block BOOL fireOnce = FALSE;
    dispatch_queue_t queue;
    queue = dispatch_queue_create("com.myapp.abcallback", NULL);

    dispatch_async(queue, ^{

        if (fireOnce == FALSE) {

            fireOnce = TRUE;

            dispatch_queue_t queueInternal;
            queueInternal = dispatch_queue_create("com.myapp.abcallbackInternal", NULL);
            dispatch_async (queueInternal, ^{
               NSLog(@"do internal logic");

            });

            dispatch_release(queueInternal);
        }
    });
    dispatch_release(queue);
}

我很确定此代码适用于接收多个通知,因此回调也是如此不同?它们是否自动生成不同的线程,每次使fireOnce值为FALSE?我应该如何编写此代码以防止多次回调多次调用内部逻辑?我想我可以使用锁和/或同步块来实现这一点,但GCD似乎是一种更清晰的方法来实现这一目标。

I'm pretty sure this code works for receiving multiple notifications, so are callbacks different? Do they spawn different threads automatically, making the fireOnce value to be FALSE each time? How should I write this code to prevent multiple callbacks from calling the internal logic more than once? I suppose I could use locks and/or synchronized blocks to achieve this, but GCD seemed like a cleaner way to achieve this.

推荐答案

我最终使用NSTimers而不是GCD来防止重复的回调触发我的关键方法。更简单,效果很好!

I ended up using NSTimers instead of GCD to prevent the duplicate callbacks from firing my critical method. Much simpler, and works quite well!

[self.changeTimer invalidate];
self.changeTimer = nil;
self.changeTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                            target:self
                                                          selector:@selector(handleAdressBookExternalCallbackBackground)
                                                          userInfo:nil
                                                           repeats:NO];

这篇关于GCD和回调 - 并发问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆