Using a single shared background thread for iOS data processing?

后端 未结 3 897
南旧
南旧 2021-02-10 06:38

I have an app where I\'m downloading a number of resources from the network, and doing some processing on each one. I don\'t want this work happening on the main thread, but it\

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-10 07:42

    Use GCD — it's the current official recommendation and it's less effort than any of the other solutions. If you explicitly need the things you pass in to occur serially (ie, as if on a single thread) then you can achieve that but it's probably smarter just to change, e.g.

    [self doCostlyTask];
    

    To:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^()
    {
        [self doCostlyTask];
    
        dispatch_async(dispatch_get_main_queue(), ^()
        {
            // most UIKit tasks are permissible only from the main queue or thread,
            // so if you want to update an UI as a result of the completed action,
            // this is a safe way to proceed
            [self costlyTaskIsFinished];
        });
    });
    

    That essentially tells the OS "do this code with low priority wherever it would be most efficient to do it". The various things you post to any of the global queues may or may not execute on the same thread as each other and as the thread that dispatched them and may or may not occur concurrently. The OS applies the rules it considers optimal.

    Exposition:

    GCD is Apple's implementation of thread pooling, and they introduced closures (as 'blocks') at the same time to make it usable. So the ^(C-style args){code} syntax is a block/closure. That is, it's code plus the state of any variables (subject to caveats) that the code references. You can store and call blocks yourself with no GCD knowledge or use.

    dispatch_async is a GCD function issues a block to the nominated queue. It executes the block on some thread at some time, and applies unspecified internal rules to do so in an optimal fashion. It'll judge that based on factors such as how many cores you have, how busy each is, what it's currently thinking on power saving (which may depend on power source), how the power costs for that specific CPU work out, etc.

    So as far as the programmer is developed, blocks make code into something you can pass around as an argument. GCD lets you request that blocks are executed according to the best scheduling the OS can manage. Blocks are very lightweight to create and copy — a lot more so than e.g. NSOperations.

    GCD goes beyond the basic asynchronous dispatch in the above example (eg, you can do a parallel for loop and wait for it to finish in a single call) but unless you have specific needs it's probably not all that relevant.

提交回复
热议问题