My program needs to load a new info into json in the background and load it into the database and I launch it like this

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ //загружаю json //запускаю запись в базу предварительно заблокировав NSManagedObjectContext }); 

everything goes fine, but when the user leaves this activity for the previous or any other, then viewWillDisappear is triggered and if the background has not finished yet, then the application hangs .. the question arises: how does the viewWillDisappear bang the background task in dispatch_async? Google did not give an answer (in android there is AsyncTask which can be canceled, but here I still do not understand.

Tell me a clue

    2 answers 2

    The fact is that you cannot stop a block that is currently running .

    It is impossible, for example, due to the fact that the block, in its essence, is an anonymous function , which cannot be directly accessed - for this it should be wrapped in a shell, like NSBlockOperation (see below).

    You can only suspend the execution of further actions in any queue ( operation queue ) or group ( dispatch group ), using, for example, dispatch_suspend() .

    In your case, it may be more convenient to use NSOperationQueue , the execution of which elements can be suspended at any time using the -cancel method of NSOperation and NSBlockOperation .


    References:

    • Thank! Used: NSOperationQueue * _queue; - (void) viewDidLoad {_queue = [[NSOperationQueue alloc] init]; [self startDownloadInBackground]; } - (void) viewWillDisappear: (BOOL) animated {[_queue cancelAllOperations]; } - (void) startDownloadInBackground {[_queque addOperationWithBlock: ^ {[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: YES]; NSData * responseData = [NSData dataWithContentsOfURL: [self makeURL]]; // parsim received [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO]; }]; } - imike

    I’ll say right away that I never worked with dispatch_async, but in iOS there are NSThread execution threads, I in such cases created a method to be executed in the background and a variable of type NSThread, pulled the method to execute using performSelectorInBackground, remembered the flow with [NSThread currentThread] in The variable mentioned above and, accordingly, could cancel this thread with the help of cancel. I do not know how suitable you are, the names could be misinterpreted as I write from memory