How to dispatch code blocks to the same thread in

2019-03-09 23:51发布

Main aspect of the question: It's about iOS. Can I somehow dispatch code blocks in a way, that they will all (a) run in background and (b) on the same thread? I want to run some time-consuming operations in background, but these have to be run on the same thread, because they involve resources, that mustn't be shared among threads.

Further technical details, if required: It's about implementing an sqlite plugin for Apache Cordova, a framework for HTML5 apps on mobile platforms. This plugin should be an implementation of WebSQL in the means of the Cordova's plugin API. (That means, it's not possible to wrap entire transactions within single blocks, what could make everything easier.)

Here is some code from Cordova's Docs:

- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
    // Check command.arguments here.
    [self.commandDelegate runInBackground:^{
        NSString* payload = nil;
        // Some blocking logic...
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
        // The sendPluginResult method is thread-safe.
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }];
}

But as far as I know, there is no guarantee, that those dispatched code blocks (see runInBackground) will run on the same thread.

8条回答
闹够了就滚
2楼-- · 2019-03-10 00:48

In GCD: no, that's not possible with the current lib dispatch.

Blocks can be executed by dispatch lib on whatever thread which is available, no matter to which queue they have been dispatched.

One exception is the main queue, which always executes its blocks on the main thread.

Please file a feature request to Apple, since it seems justified and sound. But I fear it's not feasible, otherwise it would already exist ;)

查看更多
疯言疯语
3楼-- · 2019-03-10 00:48

If you want to perform a selector in Main Thread, you can use

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

and if you want to it to perform in background thread

- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)object

and if you want to perform in any other thread use GCD(Grand Central Dispatch)

double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        //code to be executed on the main queue after delay
    });
查看更多
登录 后发表回答