dispatch_sync/async

Discussion in 'iOS Programming' started by patent10021, Mar 23, 2016.

  1. patent10021, Mar 23, 2016
    Last edited: Mar 23, 2016

    patent10021 macrumors 68020

    patent10021

    Joined:
    Apr 23, 2004
    #1
    So every junior dev like myself is told to use dispatch_sync/async for fear of the main/background thread monster.

    I get it but I'm not clear on the usage cases because documentation and blogs only ever mention dispatch_sync as it applies to network requests. They often say use it when updating the UI but what exactly defines updating the UI?

    Should I not even be using dispatch_async at all in the cases below? How about the generic main_queue? global_queue?

    What about these use cases?

    Static notification pops up for a New Friend Request and taps the View Profile button i.e.
    Code:
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) { [unowned self] in
                if let notificationIdentifier = identifier {
                    if notificationIdentifier == "ViewProfileButtonAction" {
                        self.pushControllerWithName("UserProfileController", context: nil)
                    }
                }
            }
    User taps Accept Friend button and is sent to a controller via modal segue that displays a cool "OK checkmark" animation i.e.
    Code:
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) { [unowned self] in
                    self.presentControllerWithName("OKController", context: nil)
            }
    After user taps the cool animated OK button they are sent to the main initial VC with the typical vertical menu. The OK button has technically updated the UI with 160 frames so should that stuff be inside of a dispatch?
    Code:
    override func awakeWithContext(context: AnyObject?) {
            super.awakeWithContext(context)
            dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] in
                self.buttonGroup.setBackgroundImageNamed("frame")
                self.buttonGroup.startAnimatingWithImagesInRange(NSRange(location: 0, length: 159), duration: 2, repeatCount: 1)
                self.buttonGroup.setAlpha(0.60)
            }
        }
    
    Also I've read that you should also code to avoid a hang if thread is already on main thread i.e.
    Code:
    void runOnMainQueueWithoutDeadlocking(void (^block)(void)) {     if ([NSThread isMainThread])     {         block();     }     else     {         dispatch_sync(dispatch_get_main_queue(), block);     } }
    
    runOnMainQueueWithoutDeadlocking(^{         //Do stuff     });
    
     
  2. AxoNeuron macrumors 65816

    AxoNeuron

    Joined:
    Apr 22, 2012
    Location:
    The Left Coast
    #2
    Literally anything even remotely related to UI should be done on the main thread. It's easiest to ensure you are on the main thread like this:

    Code:
    dispatch_async(dispatch_get_main_queue(), {() -> Void in
       //stuff
    }
    If you are performing a network request or doing some complicated caching operations or something NON UI related, then it's good to do this on a background thread. Some things like Apple's Core Data make switching between threads a total nightmare...but it can be done.

    Keep in mind that if you call a function from within a dispatch_async block, that function itself will be executed in the same block. So if you have a function that calls another function to update some UI, make sure to hop back to the main thread first.
     
  3. 1458279 Suspended

    1458279

    Joined:
    May 1, 2010
    Location:
    California
    #3
    It's been a little while, so I'm probably rusty, but there's an issue with which one to use that has to do with what one might need to continue.

    Example:
    Thread A needs to update a field
    Thread B needs to wait for the field to be updated in order to have the latest data.

    If you create a situation where B gets done before A, then you have a problem. If you control this, then B has to wait for A. If not handled right, you get a dead lock.

    The other issue is UI and that has to do with not making the user wait for the UI. You have a situation where the user presses "back" and you have a thread that is holding things up or is no longer needed to do it's work.

    I can't find the links/books that I got this from right now, but if you just imagine what could happen when threads dead lock. It's the same thing as locking records on a server.

    Apple pushes the user exp part and want the UI to alway be responsive.
     

Share This Page