3

I'm not very much old with DispatchQueue things (including DispatchGroups, Qos etc.). And I have a concern right now. It's like, I have a ViewController that is reused for Android's ViewPager UI. And in that VC, I have a TableView which reloads every time the "page" in the ViewPager is changed. I have a favourite button property in the TableView cell. When user tap on that button, it stores required information for a post call (JSON). I want to make the post call whenever viewWillDisappear runs. And there I want to create background threads for each "page" and catch the already created thread in case a user hits a "page" for which the post call could not culminate for any reasons. Here is what I have in my class:

var workItem1: DispatchWorkItem!
var dispatch1: DispatchQueue!

and

override func viewWillDisappear(_ animated: Bool) {
     super.viewWillDisappear(animated)
}

What should I do to achieve my goal?

  • Do I understand you correctly that you only want multiple queues in case one call throws an exception? – TMob Jul 11 '18 at 13:56
  • 1
    There's no need for queues for this at all. `URLSession` is already asynchronous. Queues are not threads. If you are used to threaded-programming see Apple's guide on migrating to queues, which is a different way of thinking about the problem. (Though again, there is no need for queues here; `URLSession` already has its own queues to manage this for you.) https://developer.apple.com/library/archive/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW1 – Rob Napier Jul 11 '18 at 14:18
  • 1
    See also https://developer.apple.com/documentation/foundation/url_loading_system for an introduction to URLSession and how to think about it. It is an asynchronous system; there is no need to create new threads or queues to manage it (and you generally should not do so). – Rob Napier Jul 11 '18 at 14:19
  • @TMob It's somehow partial. I don't really want **many** queues but I want queues to control them and terminate or suspend in case I need to make another API call before the already created ones return some response. –  Jul 12 '18 at 17:36
  • I need guidance for both **URLSession** and and **queues**. I see I am wrong in perceiving the whole concept of threads. My concern is just that I want to control the threads and terminate or suspend in case I need to make another API call before the already created ones return some response. –  Jul 12 '18 at 17:39
  • Thank you for your comments! –  Jul 12 '18 at 17:40
  • I have got a way for that, I am holding the task I'd like to control in an instance of `DispatchWorkItem`. And whenever `viewWillDisappear` runs I'm cancelling the task if it's not nil like `if workItem != nil { self,workItem.cancel()}`. Is it a good practice? –  Jul 12 '18 at 17:47

1 Answers1

2

You can theoretically create as many queues as you need. You can also choose between a serial queue (tasks are being worked on after each other) or a concurrent queue (tasks are being worked on concurrently)

let concurrentQueue = DispatchQueue(label: "my_queue_1", attributes: .concurrent)
concurrentQueue.sync {
    //do your thing
}  

BUT: It's bad practice to create a queue for each call. Thats not what queues are for. What you should do instead is use a concurrent queue where every task represents a POST-call.

Or even better you should ask yourself if you can't just submit an array of all the pages the user has favourited to the server in one go. This would eliminate the need for a queue somewhat.

TMob
  • 1,278
  • 1
  • 13
  • 33
  • Thanks for the answer! But in this case I am using the same viewController for each page because all of them require the same UI structure. Therefore I can't submit all of them together. `Page A` has 5 items and `Page B` has 3 items. I am on `Page A` and I skip `Page B` and go to `Page D` instead. So, all of the tasks that were called in `viewWillAppear` will keep running until completion. I want to stop execution of the tasks or some them to `suspend` or `cancel` if I am not viewing the corresponding page. That's all. –  Jul 12 '18 at 17:45
  • Suspending already running tasks is possible but annoying. The question is why do you want to suspend them? Is it just a performance-issue or does your application logic rely on not having those requests sent? – TMob Jul 13 '18 at 06:59
  • My application doesn't rely on that. I thought this would be a good way to optimise the performance. Because the pod file that provides ViewPager UI isn't that much handy with performance. Like, if I scroll directly from **Page A** to **Page E**, `viewWillAppear` will be called for all of the pages from A to E. And hence the results for the API call for Pages B, C, D will be discarded unused. That is irritating me. So, I'd like to be guided. more on this topic. _What should I do to minimise memory and internet usage in this case?_ **Thank you!** –  Jul 15 '18 at 17:42