1

If a second method is called from a method that is running on a background thread, is the second method automatically ran in that same thread or does it happen back on the main thread?

Note: I want my second method to be handled in the background, but since I update the UI inside it, would doing the following, be the right way to do it:

- (void)firstMethod {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        //Do stuff in background
        ...

        //Call a second method (Assume it'll run in this background thread as well)
        [self secondMethod];
    });
}

//Second Method

- (void)secondMethod {

    //Do heavy lifting here
    ...

    dispatch_async(dispatch_get_main_queue(), ^{

        //Update UI here
        ...

    });
}

Update

Oh I totally forgot to mention that this method is something that loads suggestions into the view (think keyboard suggestions). Since every key tap would be calling this method, I only want it to run when a user has finished typing. The way I'm approaching it is by setting a 0.2 delay between keys and if a new key tap fall within that 0.2 delay it cancels the previous method call, and initiates a new call (this way, assuming the use types the word, "the", it doesn't run suggestions for "t", "th", "the". Since the user is typing pretty quickly we can assume they don't want suggestions for anything until they have stopped typing (allowing the call to go through after a 0.2s delay), or if they type slow (where they probably are looking for suggestions along the way).

So when calling my secondMethod I do the following:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(secondMethod) object:nil];
[self performSelector:@selector(secondMethod) withObject:nil afterDelay:0.2];

The problem is it's not being called (I'm assuming this method defaults it to be performed in the main thread?)

5
  • It looks perfectly fine structurally, but I'm not sure it's wise to choose DISPATCH_QUEUE_PRIORITY_HIGH. But your threading is doing exactly what you want. Very good! Commented Jan 19, 2015 at 3:35
  • Thanks Matt! Just updated my answer with more info on my usage case. Would you recommend Default? If so, how come? Commented Jan 19, 2015 at 3:49
  • In my experience, if you're not actively seeing problems due to contention between threads of the same priority, it's less hassle to leave everything at default. The system will (in iOS 8/Yosemite at least) auto-propagate priority boosts from the main thread anyway. Commented Jan 19, 2015 at 3:57
  • Sorry, but your edit is a completely different question. It has nothing to do with threading. Please ask it as a completely different question! - However, I would say this: you should not be doing anything in a background thread that you depend upon to happen any time soon. Now that you've revealed this, I don't see why this is a candidate for background threading at all. Commented Jan 19, 2015 at 3:57
  • Thanks Matt, it still is the same question. The only difference is in how I'm calling the second method. Also the reason why I'm using a background thread, is because if my method calls happens on the main thread it slows down the UI, resulting in horrible lag between taps. Therefore moving it to the background, improves interaction performance. Once the query for suggestions has completed, I update the UI without interfering with the user's continuous taps. Commented Jan 19, 2015 at 4:01

1 Answer 1

2

Generally speaking, nothing is going to hop between threads without being pretty explicit about it. Certainly something as trivial as just calling a method isn't. Your code seems fine. Remember to not access mutable state from more than one queue at once (for example if the heavy lifting uses instance variables, make sure that -firstMethod doesn't get called twice in a row. It'd spawn off two async calls to -secondMethod then, and they'd step all over each others data. If that's a problem, create a serial dispatch queue instead of using a global one).

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the info! I left out some crucial info that may change things :\ just updated my answer!
Ok, the -performSelector:afterDelay: methods are all runloop-based, and generally aren't going to interact with dispatch queues in ways that you'd expect. You probably want to use dispatch_after() instead.
Thanks Catfish_Man is there a way to cancel those as well? The way ```-performSelector:afterDelay:```` allows one to.
Oh, right, argh, that's a bit tricky. I guess you can use dispatch_source_t set up as a timer. dispatch_after is just a wrapper around that.
Will definitely look into that!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.