How to create a timer in background thread in iOS - ios

I need to create two timers. One is on the UI thread, the other one is on the background thread. These timers are independent from each other.
Scenario that I will be using; I basically need this to test the responsiveness of UI thread. TImer in uI thread updates lastUpdatedDatetime property every 200ms in UI thread. There is also a background thread that polls this lastupdatedDatetime property every 200ms.
Does anyone know how can I achieve this?

The point of NSTimer is to be able to schedule things to be run on a thread (usually the main thread) while it is handling other events on a run loop. If all you want to do on the background thread is to poll something every 200 ms, then it is far easier to not use an NSTimer and to instead just sleep the background thread. So setup an NSTimer as usual on your main thread and on the background thread do something like:
while (stillRunning) {
usleep(200*1000);
// Do something with lastUpdatedDatetime
}
This technique is wasteful of a thread but is probably more deterministic for testing purposes than using Grand Central Dispatch.
Keep in mind if lastUpdatedDatetime is an NSDate that it should be set as an atomic property so that when you access it on the background thread you are sure to receive a valid object.

look into dispatch_async and dispatch_after
dispatch_async will let you fire off a call to another thread, this is what I use to do main thread changes.
dispatch_after will let you delay a dispatch_async for a number of seconds.
These two in conjunction will let you go back and forth between threads.
here is the documents on Grand Central Dispatch

Related

How does the use of NSOperation mainqueue makes UITableView's scrolling smooth?

I wonder how the process associated with NSOperation mainQueue doesn’t affect UITableView's scrolling.
The main reason of the sluggish scroll in my code is that each cell loading is slow, because each cell has to fetch images from the server.
That’s why I used to create another thread using GCD to handle the fetching process given by each cell. Meanwhile, the main thread handles exclusively tableview’s scroll, which is what I've understood to ensure fast scrolling.
But, in recent days, I’ve noticed a sample code is using NSOperation.
I imitated the part so that the tableview cell is loaded using NSOperation mainQueue.
I expected it would tax the tableview’s scroll performance, because the main thread handles both cell loading and tableview scrolling as I understand.
But, surprisingly, it doesn’t. The performance of both cell loading and tableview’s scrolling is perfect.
I still wonder how this can be.
I guess I’m either mistaken or I miss something.
Would you let me know what it is?
All iOS UI animations (including scrolling) are performed on separate UI thread. So as long as UITableView has all required data (i.e. you provide empty cell until image is loaded) it won't be blocked by any sort of main thread activity.
Execution of the animations occurs on a secondary thread so as to
avoid blocking the current thread or your application’s main thread.
https://developer.apple.com/.../AnimatingViews.html
The iOS application's main thread consists of two elements:
• The Run Loop
• The Main Queue
The main dispatch queue is a globally available serial queue that
executes tasks on the application’s main thread. This queue works with
the application’s run loop (if one is present) to interleave the
execution of queued tasks with the execution of other event sources
attached to the run loop. Because it runs on your application’s main
thread, the main queue is often used as a key synchronization point
for an application.
Source
The code you have in your View Controllers is ran on the run loop (not sure about this one). That's why you're not allowed to execute any long lasting tasks.
You can though, delegate these tasks to the Main Queue (and that's what you're doing). When you do that, the OS interleaves the execution between the run loop and the main queue (loading the images). That's why scrolling the view is still pretty smooth.
Why don't we do all async tasks on the main queue then? you might ask. Because the main queue has to share thread processor time with the run loop, operations will be executed slower than on a background thread. It's not something that you can observe in that example, though.

How to schedule an asynchronous task every 'x' seconds when main and background thread need same data?

I have an iOS application that has an NSTimer which fires every 5 seconds. This then posts a notification, telling several controllers that they must now recalculate some data and then update their UI.
When this all happens on the main thread, scrollviews can become jittery as the data is processed.
Using GCD, I have wrapped the code called when a notification is posted:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Code here
dispatch_async(dispatch_get_main_queue(), ^(){
// Reload tableviews and UI
};
};
Unfortunately, this leads in certain cases to several threads accessing the same instance variables. This causes my application to crash as sometimes it ends up mutating an array being enumerated in another thread.
Wrapping the code in a synchronised block prevents this.
When the user scrolls the tableview, several methods are called to calculate the height etc, on the main thread. The code within the background thread is working on the code needed by the main thread. As such, this can usually further cause crashes
I have tried setting the variables to 'atomic', but this doesn't solve the issue. Ideally, I don't want to have the main thread waiting on the background thread, but I am not sure how to best resolve this issue given that they need the same data?
This is pretty classic multithreaded programming issues. There are a number of ways to solve it with basic locks (#synchronized blocks), reader/writer locks, etc but the problem is often that you can't control when the user is going to scroll or take other action. If you #synchronize, you have to do it anywhere that data is touched, including your UITableView data source methods. That can lead to stuttering if the background processing happens to be in the middle of something.**
Personally, I would use an immutable snapshot mechanism.
Have the background thread produce the results, then include just the data the UI needs to display in the notification data as an immutable snapshot (copy). That way the background thread never modifies the data the UI is currently reading for display. How you would implement this is highly dependent on how much data you are talking about and the form it takes, but the safe way would be to have copies of your classes with readonly properties. Alternatively, you can use a "frozen" flag. Make a copy, then set frozen = YES on the copy. The UI thread will only ever see "frozen" or readonly objects coming from the background thread.
The benefit is the UI never causes the background thread to stall and there are no locks required. The downside is increased memory usage, though if the amount of data is large you can use copy-on-write mechanisms to allow the background thread and UI thread to share the data, even though logically the UI thread has a completely separate copy.
** Note: In most applications, you don't have this sort of continuous background processing going on so those apps can use simpler mechanisms. This is typically a form of message passing where the background thread finishes its task and "passes the message" to the UI thread (passes the results). At that point the background work is finished so there is no concurrent modification happening.

DrawRect not called due to active main thread

I have an architecture that takes input from the mic and then performs some calculations and then should render to screen.
The issue is that calling setNeedsDisplay never triggers a call to drawRect because the main thread is running the calculations.
What would be the best way to thread this?
Create a single serial queue and dispatch the work to this background queue using GCD and dispatch the final setNeedsDisplay back to the main queue, or is there a more efficient way of doing this?
keep everything long running off the main thread. that is best in my opinion. Long running calculations are also something
try to never block the UIThread
...work to this background queue using GCD and dispatch the final
setNeedsDisplay back to the main queue, or is there a more efficient
way of doing this?
Based on your pretty vague description, I'd say what you suggested is the best approach.
And if you do this with GCD, your code will be easy to read since the blocks of work you perform are inline in your code making it easy to understand what is going on.
Create a single serial queue and dispatch the work to this background queue using GCD and dispatch the final setNeedsDisplay back to the main queue, or is there a more efficient way of doing this?
You should use the highest level API available to you. In this case, it's NSOperation or one of its subclasses. Probably, NSBlockOperation is the one you want. You should
create a block operation with the block you want executing
Set its completion handler to invoke setNeedsDisplay
Stick it on an NSOperationQueue.
The completion handler needs to invoke setNeedsDisplay on the main thread. You can do this by sending performSelectorOnMainThread:withObject:waitUntilDone: to the view e.g.
[myViewThatNeedsUpdating performSelectorOnMainThread: #selector(setNeedsDisplay)
withObject: nil
waitUntilDone: NO];
I think this is a better approach than using GCD directly because it is more in the Objective-C idiom, it separates the work you are doing from the notification at the end and gives you many more options for how things get done than raw GCD. For instance, if you want several of these things to happen sequentially, you can make some operations dependencies of others without having to write lots of code.

How do I prepare my UI in a background thread?

A UIViewController takes about half a second to load its contents and appear on screen. How can I make them all load in the background and appear when they're ready?
There is a LazyTableImages sample on the Apple developer site.
It shows how to perform the heavy lifting in a background thread and update the UI on the main thread.
PerformSelectorInBackground:withObject: is a possible solution, although a more modern method would be to use asynchronous blocks. You can run code on the main thread from within these blocks to update the UI Safely.
The Concurrency Programming Guide is a good place to find more information and examples of this.
A Background Thread cant update the UI,you can perform all the processing logic in background thread and call the main thread for UI update
Example to load a tableView with Data ,use the background thread to process everything and load the Data, call [tableView reloadData] using the main thread, see Grand central Dispatching to know how to Work with Threads in IOS..
Hope it Helps
Create a GCD queue to process your work in a background thread (read the docs, because my "create" label and options may not be what you want).
You send it to the queue asynchronously, meaning that the call to dispatch_async will make appropriate arrangements for the block of code you give it to run in another thread and it will then return back to you "immediately."
All the work in the block you give it will be executed on a separate thread. Note, at the end, you do another call, this time with the well know main queue. This arranges for that code to run in the main thread, which is mandatory for any UI work.
Also, you really should read the documentation on GCD and especially blocks, because there are memory and cycle considerations. Good luck.
dispatch_queue_t workQ = dispatch_queue_create("bgWorkQ", 0);
dispatch_async(workQ, ^{
// This code is now running in a background thread.
// Do all your loading here...
// When ready to touch the UI, you must do that in the main thread...
disptach_async(dispatch_get_main_queue(), ^{
// Now, this code is running in the main thread.
// Update your UI...
});
});
dispatch_release(workQ);
The easiest way is to use NSObject's - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg You just pass it a selector and it will happy in the background and not block your UI. Be aware however that there are rules to background threads.
You shouldn't update your UI from the background thread. And you need to make sure the methods you're calling are thread safe.

Pausing particular thread in iOS?

in my iPhone app, I have used 2 threads. Both functions differently in different class. On particular condition I want to pause particular thread so I have used
[NSThread sleepForTimeInterval:]
So my question is am I doing right or this sleep causes sleep in whole application? If yes what is other alternative?
If you want to pause your thread for a given amount of time, then [NSThread sleepForTimeInterval:] is just fine. However if you want to wait for a given event to occur (e.g. wait for another thread to catch up) you should take a look at the NSCondition class.
Yeah this is absolutely right. This will pause the current thread on which you are calling [NSThread sleepForTimeInterval:]

Resources