0

I have an asynchronous dispatch queue which reads data from large files in the background. During the course of that it does a few other things including some NSTask operations. The problem I'm facing is that I populate some variables with the result of those operations and the background queue has already moved on by the time those variables are ready (not NULL).

My code looks similar to the following:

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{

    // reading large files
    ...
    NSTaskClass *operation = [[NSTaskClass alloc] init];
    NSString *result = [operation doTask:filePath];

    NSLog(@"result: %@" result); // returns NULL since task isn't done yet.
    ...
    // continue large file operations
});

Would would be the best way to handle this? I looked into creating a callback but I couldn't figure it out, and I'm not sure if that's even the right approach. Any advice on best practices is appreciated, thanks.

Joe Habadas
  • 628
  • 8
  • 21
  • It's not background, it's another process. Do you really need read large file in another process? It's only make sense if you are running some server. – Cy-4AH Nov 16 '19 at 08:37

1 Answers1

0

Just give you an idea, hope to solve your problem.

  • Use a dispatch_sempahore to handle the operations in your NSTaskClass
  • Create a handler for doTask method, use - (void)doTask:(NSString *)filePath handler:(void(^)(NSString *result))handler instead of - (NSString *)doTask:(NSString *)filePath

Then, your code should look something like this:

    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{

        // reading large files
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);

        ...
        NSTaskClass *operation = [[NSTaskClass alloc] init];
        [operation doTask:filePath handler:^(NSString * _Nonnull result) {
            // Get your result here
            result = [NSString stringWithString:result];

            ...

            dispatch_semaphore_signal(sema);


        }];

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

        NSLog(@"result: %@" result); // Here should be fine (not NULL)
        ...
        // continue large file operations
    });
htq287
  • 113
  • 7
  • Hi, I tried your suggestion but it seems like once I call my `NSTaskClass` it never returns. I'm not exactly sure why. If you need any more information let me know, because I would like to get this working, thanks. – Joe Habadas Nov 16 '19 at 11:04
  • @JoeHabadas So, any background jobs in the object of `NSTaskClass`? If possible, could you please give me more detail about your code – htq287 Nov 16 '19 at 13:44