开发者

How to share Serial Dispatch Queues between classes?

开发者 https://www.devze.com 2023-03-23 04:46 出处:网络
I noticed that they don\'t return pointers when created, but actual objects. So to get a pointer, I\'m trying to declare it like this:

I noticed that they don't return pointers when created, but actual objects. So to get a pointer, I'm trying to declare it like this:

dispatch_queue_t* queue;
*queue =开发者_运维知识库 dispatch_queue_create("double_buffer_protection_queue", DISPATCH_QUEUE_SERIAL);

The C++ programmer in me says that should work, but it gives a BAD_ACCESS error, so I'm guessing I'm approaching this the wrong way.

If I want a serial queue that can be accessed by any object in my program, how do I do it? The code I showed above was meant to go in the AppDelegate class.


From the GCD Reference: typedef struct dispatch_queue_s *dispatch_queue_t;

Maybe I'm barking up the wrong tree, but my gut would tell me a more idiomatic solution might be to use the dispatch_once function inside a class method to yield a queue that multiple class instances can send work to (it's not C++ but you get the basic idea):

+ (dispatch_queue_t)sharedQueue
{
    static dispatch_once_t pred;
    static dispatch_queue_t sharedDispatchQueue;

    dispatch_once(&pred, ^{
        sharedDispatchQueue = dispatch_queue_create("theSharedQueue", NULL);
    });

    return sharedDispatchQueue;
}

dispatch_once ensures the queue creation happens only once during the entire runtime so you can call [YourClass sharedQueue] safely and cheaply as often as you need, wherever you need it.

However my gut would also tell me that sharing queues between classes / objects smells just a little bit bad. If you just want an app-wide queue to submit miscellaneous jobs to, would the global queue suffice? If you want to do some intensive work with large collections of objects, I'd instinctively set up a separate queue for them. Maybe there's a more elegant way of doing what you want?


In Grand Central Dispatch, using actual objects is proper way. For instance,

class Manager
{
    Manager()
    {
        m_queue = dispatch_queue_create("double_buffer_protection_queue", DISPATCH_QUEUE_SERIAL);

        m_worker = new Worker(m_queue);
    }

    ~Manager()
    {
        dispatch_release(m_queue);
        delete m_worker;
    }

    dispatch_queue_t m_queue;
    Worker *m_worker;
}

And then the another owner of the queue must retain and release it by itself like Objective-C objects.

class Worker
{
    Worker(dispatch_queue_t queue)
    // Worker(dispatch_queue_t &queue) /* reference might be ok. */
    {
        m_queue = queue;
        dispatch_retain(m_queue);
    }

    ~Worker()
    {
        dispatch_release(m_queue);
    }

    dispatch_queue_t m_queue;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消