ios loop for asynchronous requests - iphone

I have to make multiple http requests asynchronously (one request at a time). For looping I am doing this:
-(void) Foo1
{
[makerequest];
}
-(void) requestCompletes
{
//Do something
[self Foo1:[array objectAtIndex:i++]];
}
viewDidLoad
{
[self Foo1:[array objectAtIndex:0]];
}
But looping in the completion-handler doesn't seems a good idea to me. Is this the correct way?

No, this is not the correct way. The iOS platform has a NSOperationQueue class, which allows you to schedule operations. By creating you're own subclass of any of the operations (NSInvocationOperation, NSBlockOperation or the NSOperation) and using it to wrap around a NSURLRequest you can easily add and execute web request by calling
[operationQueue addOperation:requestOperation];

Related

Passing data between classes / asynchronous requests / iOS

I am converting my application from Syncronous to Asyncronous HTTP requests and have ran into a problem that looks like it will require quite a big reworking of how the application handles its data. Let me try to explain
Previously it was like this:
-Class1, Class2 and Class3 were all subclasses of UIViewController
-Helper class
-Content display class
They do broadly different things but the common trait is their interaction with the helper class. They gather details of a request in a number of different ways from a user and then eventually send a request to the helper class.
When it was done syncronously the helper class would return the data. Each class would then interpret the data (XML files) and pass them on to the Content display class via a segue
So something broadly like this:
Class1:
//Get user input
SomeData *data = [helperclass makerequest];
id vcData = [data process];
[self performSegueWithIdentifier:#"segueIdentifier"];
---
- (void)prepareForSegue:(UIStoryboardSegue *)segue
{
DestinationViewController *destination = (DestinationViewController *)segue.destinationViewController;
destination.data = vcData;
}
Content display class:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.data presentdata];
}
Now it looks like this
I dealt with this problem by first making it work with Class1 with a view to deploying the fix to class2 and class3. So class1 and helper now interact like this
Class1:
//Get user input
SomeData *data = [helperclass makerequestWithSender:self];
id vcData = [data process];
[self performSegueWithIdentifier:#"segueIdentifier"];
---
- (void)prepareForSegue:(UIStoryboardSegue *)segue
{
DestinationViewController *destination = (DestinationViewController *)segue.destinationViewController;
destination.data = vcData;
}
Now the biggest problem I am facing is how to get the data from helperclass back to Class1. I managed to get it to work by doing
(void)makeRequestWithSender:(Class1*)sender
{
[NSURLConnection sendAsynchronousRequest:...
{
[sender sendData:data];
}
}
However, when I have came to roll this out to the other 2 GUI classed which will compose the request I am having difficulty with. My first thought was to set sender:(id) but that fails at the line [sender sendData:data] telling me that id does not have an method sendData: or similar.
Hopefully I wasn't too vague here and you guys can help. If required I will be able to post code snippets but for now can anyone help with a better suggestion about how to structure the code for this request?
You basically want to use the 'observer pattern' or a (maybe) slightly changed setup, so you can use delegation.
Observer pattern
You gain the mechanic via the NSNotificationCenter and NSNotifications. Your 3 different UIViewController subclasses each subscribe to a specific NSNotification and you notify them via posting a notification via the NSNotificationCenter.
The following code is an example of how you can approach the problem in your viewcontroller subclasses:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// subscribe to a specific notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doSomethingWithTheData:) name:#"MyDataChangedNotification" object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// do not forget to unsubscribe the observer, or you may experience crashes towards a deallocated observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
...
- (void)doSomethingWithTheData:(NSNotification *)notification {
// you grab your data our of the notifications userinfo
MyDataObject *myChangedData = [[notification userInfo] objectForKey:#"myChangedDataKey"];
...
}
In your helper class, after the data changed you have to inform the observers, e.g.
-(void)myDataDidChangeHere {
MyDataObject *myChangedData = ...;
// you can add you data to the notification (to later access it in your viewcontrollers)
[[NSNotificationCenter defaultCenter] postNotificationName:#"MyDataChangedNotification" object:nil userInfo:#{#"myChangedDataKey" : myChangedData}];
}
via #protocol
Presuming all your UIViewController subclasses reside in a parent viewcontroller, you can implement a protocol in your helper class and make the parent viewcontroller the delegate. Then the parent viewcontroller may inform the child uiviewcontrollers via passing a message.
Your helper class declaration could look like this (presuming ARC):
#protocol HelperDelegate;
#interface Helper : NSObject
#property (nonatomic, weak) id<HelperDelegate> delegate;
...
#end
#protocol HelperDelegate <NSObject>
-(void)helper:(Helper *)helper dataDidChange:(MyDataObject*)data;
#end
In the helper implementation you would inform the delegate via:
...
if ([self.delegate respondsToSelector:#selector(helper:dataDidChange:)]) {
[self.delegate helper:self dataDidChange:myChangedDataObject];
}
...
Your parent viewcontroller would need to be the delegate of the helper class and implement its protocol; a rough sketch, in the declaration
#interface ParentViewController : UIViewController <HelperDelegate>
and for the implementation in short version
// you alloc init your helper and assign the delegate to self, also of course implement the delegate method
-(void)helper:(Helper *)helper dataDidChange:(MyDataObject*)data {
[self.myCustomChildViewController doSomethingWithTheNewData:data];
}
Besides..
You might ask yourself which method to prefer. Both are viable, the main difference is that via the observer pattern you get more objects to be informed 'at once', whereas a protocol can only have one delegate and that one has to forward the message if needed. There are a lot of discussions around about pros and cons. I'd suggest you read up on them once you made up your mind (sorry ain't got enough reputation to post more than two links, so please search on stackoverflow). If something is unclear, please ask.
Some reasonable ideas here. To elaborate/add my opinion:
First, which object ought to tell the downloader (HelperClass) to begin downloading? My practice is to do this in the view controller that will present the data. So I generally start network requests after a segue (like in viewWillAppear: of the presented vc), not before.
Next, when one class needs to execute code provided for another, I first think about if it makes sense to do it using a block. Very often (not always) blocks make more sense and provide more readable code than, say, delegate, notification, KVO, etc. I think NSURLConnection completion, for example, is better suited to blocks than delegate. (and Apple kind of agrees, having introduced + (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler).
So my pattern for your app would be this:
// Class1.m
// when user has completed providing input
...
// don't do any request yet. just start a segue
[self performSegueWithIdentifier:#"ToContentDisplayClass" sender:self];
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// don't do a request yet, just marshall the data needed for the request
// and send it to the vc who actually cares about the request/result
if ([segue.identifier isEqualToString:#"ToContentDisplayClass"]) {
NSArray *userInput = // collect user input in a collection or custom object
ContentDisplayClass *vc = segue.destinationViewController;
vc.dataNeededForRequest = userInput;
}
...
Then in ContentDisplayClass.m
// this is the class that will present the result, let it make the request
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
HelperClass *helper = [[HelperClass alloc]
initWithDataNeededForRequest:self.dataNeededForRequest];
// helper class forms a request using the data provided from the original vc,
// then...
[helper sendRequestWithCompletion:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
// interpret data, update view
self.label.text = // string we pulled out of data
} else {
// present an AlertView? dismiss this vc?
}
}];
This depends on HelperClass implementing the block form of NSURLConnection
// HelperClass.m
- (id)initWithDataNeededForRequest:(id)dataNeededForRequest {
// standard init pattern, set properties from the param
}
- (void)sendRequestWithCompletion:(void (^)(NSURLResponse *, NSData *, NSError *))completion {
NSURLRequest *request = ...
// the stuff we need to formulate the request has been setup in init
// use NSURLConnection block method
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:completion];
}
Edit - there are several rationale's for making the VC transition before starting the network request:
1) Build the standard behavior around the success case: unless the app is about testing network connections, the success case is that the request works.
2) The cardinal principal for an app is to be responsive, to do something sensible immediately upon user actions. So when the user does something to initiate the request, an immediate vc transition is good. (what instead? a spinner?). The newly presented UI might even reduce the perceived latency of the request by giving user something new to look at while it runs.
3) What should an app do when a request fails? If the app doesn't really need the request to be useful, then doing nothing is a good option, so you'd want to be on the new vc. More typically, the request is necessary to proceed. The UI should be "responsive" to request failure, too. Typical behavior is to present an alert that offers some form of "retry" or "cancel". For either choice, the place the UI wants to be is on the new vc. Retry is more obvious, because that's where it always is when it tries to fetch the data. For cancel, the way to be "responsive" to cancel is to go back to the old vc, a vc transition back isn't ugly, it's what the user just asked for.
I'm not 100% clear on how you're handling the data now, but to change your data to asynchronous calls, I would use blocks. For instance your current synchronous code like this:
//Get user input
data = [helperclass makerequest]
sendData = [data process]
would turn into something like this:
//Get user input
data = [helperclass makerequestWithSuccess:^{
sendData = [data process]
}];
Using a success block will allow you to wait to process the data until the makerequest was finished.
Your new makerequest function would now look like this:
-(void)makerequestWithSuccess:(void (^)(void))success{
// Put your makerequest code here
// After your makerequest is completed successfully, call:
success();
}
Hope this helps!
I'm not sure that I understood your problem correctly, but if it's sort of:
Start task A asynchronously.
When task A finished successfully, get its result and start task B whose input is result A.
When task B finished successfully, get its result and start task C whose input is result B.
...
When finished successfully, be happy, otherwise print error.
A code example would look like this:
typedef (void)(^completion_block_t)(id result);
-(void) asyncTaskA:(completion_block_t)completionHandler;
-(void) asyncTaskBWithInput:(id)input completion:(completion_block_t)completionHandler;
-(void) asyncTaskCWithInput:(id)input completion:(completion_block_t)completionHandler;
-(void) asyncSomethingWithCompletion:(completion_block_t)completionHandler;
-(void) asyncSomethingWithCompletion:(completion_block_t)completionHandler
{
[self asyncTaskA:^(id resultA){
if (![resultA isKindOfClass:[NSError class]]) {
[self asyncTaskBWithInput:resultA completion:^(id resultB){
if (![resultB isKindOfClass:[NSError class]]) {
[self asyncTaskCWithInput:resultB completion:^(id resultC) {
completionHandler(resultC);
}];
}
else {
completionHandler(resultB); // error;
}
}];
}
else {
completionHandler(resultA); // error
}
}];
}
And you use it like:
[self asyncSomethingWithCompletion:^(id result){
if ([result isKindOfClass:[NSError class]]) {
NSLog(#"ERROR: %#", error);
}
else {
// success!
self.myData = result;
}
}];
The "continuation" and error handling makes this a bit confusing (and Objective-C syntax doesn't really add for more readability).
Another example with a third party library support:
The same logic can be written as this:
-(Promise*) asyncTaskA;
-(Promise*) asyncTaskBWithInput;
-(Promise*) asyncTaskCWithInput;
-(Promise*) asyncSomething;
- (Promise*) asyncSomething
{
return [self asyncTaskA]
.then(id^(id result) {
return [self asyncTaskBWithInput:result];
}, nil)
.then(id^(id result) {
return [self asyncTaskCWithInput:result];
}, nil);
}
And it is used as follows:
[self asyncSomething]
.then(^(id result) {
self.myData = result;
return nil;
},
^id(NSError* error) {
NSLog(#"ERROR: %#", error);
return nil;
});
If you like the latter more, the "Promise" framework is available on GitHub: RXPromise - I'm the author ;)
I'm not sure if what I've done in the past is relevant to your problem, but what I've done is create a download class that has a delegate protocol with a single method: -(void)downloadFinished:(id) data.
Any class that needs to get asynchronous data, creates an instance of this download class, and sets itself as the delegate. I call downloadFinished: from both connection:didFailWithError: and connectionDidFinishLoading:. Then, in the implementation of that method in the delegate, I check whether the data's class is NSData or NSError, and evaluate that data however is appropriate for that class.

How to request JSON data in the viewDidAppear method or viewDidLoad?

If I call the [self requestData]; from viewDidLoad my table populates itself with data just fine. If I move [self requestData]; to the viewDidAppear method the table remains empty.
Also, I'm not entirely sure if [self.mainTableView reloadData]; is working. I'm trying to move the data request and handling to the viewDidAppear method because I saw that pattern in a code example and thought it might speed up my app launch somewhat. At the moment there's quite a lag from the app launch Default.png to the rootViewController.
thanks for any help with this.
-(void)viewDidAppear:(BOOL)animated
{
[self requestData];
}
-(void)requestData {
[HUD showUIBlockingIndicatorWithText:#"Fetching JSON"];
NSError *requestError = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
URLWithString:kURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&requestError];
NSError *jsonParsingError = nil;
if (requestError)
{
NSLog(#"sync. request failed with error: %#", requestError);
}
else
{
// handle data
publicData = [NSJSONSerialization JSONObjectWithData:response
options:0
error:&jsonParsingError];
publicDataArray = [publicData objectForKey:#"data"];
}
/*
for(publicDataDict in publicDataArray) {
NSLog(#"data output is %#",[publicDataDict objectForKey:#"title"]);
}
*/
[self.mainTableView reloadData];
NSLog(#"reload table cat id %#", categoryString);
[HUD hideUIBlockingIndicator];
}
You're trying to optimise the wrong thing.
The reason you have a lag is that your url request is synchronous, so it is blocking the main thread while waiting for the data to be received. Using an asynchronous URL request will give you far better performance benefits that moving the loading call as you are trying to do.
viewDidLoad is the right place to make your JSON request because It is called once, and will keep data into memory.
ViewDidAppear is called each time view appear, it is not really made to retain object
The "lag" is the fact that your UI is not being responsive because the JSON post request is on the main thread.
to speed up launching try to load data asynchronously, like this:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self requestData];
}];
you shoud call it inside viewDidLoad
viewDidLoad is called after the views have been created, but before they're drawn.
viewDidAppear is called after the views have been drawn. It's too late to set data here that affects the display. You could possibly load the data in viewWillAppear, but be aware that it may be called multiple times (e.g. switching between apps).
That's why setting data that affects the display works in viewDidLoad, but not viewDidAppear. viewDidLoad is called only once in a view controller's life cycle.
However, consider the user experience if your user's Internet connection is slow or the server is slow to respond. Your application will seem to "freeze" for awhile.
Instead of a synchronous request, consider using an asynchronous request. You could display a "loading" message, spinner, or something until the request returns, then update the UI directly.
Apple strongly recommends always making asynchronous requests when run from the main UI thread.

How to pass string to handling main thread operation function

Hi i want to pass string to updateProgressBar function in my code to display some data. so how i can do it
[self performSelectorOnMainThread:#selector(updateProgressBar) withObject:nil waitUntilDone:NO];
and my function look like this
-(void)updateProgressBar
{
lbl.text = ?
}
There are different ways to pass argument on your updateProgressBar.
You can do like this
NSString * alpha;
//assign some value to alpha
[self performSelectorOnMainThread:#selector(updateProgressBar:) withObject:alpha waitUntilDone:NO];
-(void)updateProgressBar:(NSString *)beta
{
lbl.text = beta;
}
OR you can also pass multiple arguments using performSelectorOnMainThread.
you can search on google many tutorials are present about this.
You can use GCD to avoid writing a separate method:
dispatch_async(dispatch_get_main_queue(), ^{
lbl.text = newLabel;
});
To address the issue described in the comments on this answer (__NSAutoreleaseNoPool(): Object 0x55f3ec0 of class NSCFString autoreleased with no pool in place):
You are most likely executing this snippet in a background thread without an autorelease pool. You can either create one or avoid using autorelease.

If a method is called at the exact same time twice, how to only execute it once?

We have a method in the iPhone SDK that is a delegate method. Problem is, the OS calls this method twice at the exact same time. This method does some heavy lifting so I don't want to execute the logic twice. What is a good way to detect this and prevent one of the two from running?
Forgot to mention that, it is called from different threads.
One method is a BOOL member that you set when entering the method and clear on leaving it. If the variable is set upon entry, you know it's already executing and can just return.
Assuming you're being called from multiple threads, you'll want to lock access to this critical area of checking/setting. An NSLock is good for this.
The code below has two implementations: myMethod1 which uses NSLock and myMethod2 which shows using #synchronize.
#interface MyClass : NSObject
{
NSLock* theLock;
BOOL isRunning;
}
#end
#implementation MyClass
-(id)init
{
self = [super init];
if(self != nil)
{
theLock = [[NSLock alloc] init];
isRunning = NO;
}
return self;
}
-(void)dealloc
{
[theLock release];
[super dealloc];
}
// Use NSLock to guard the critical areas
-(void)myMethod1
{
[theLock lock];
if(isRunning == YES)
{
[theLock unlock]; // Unlock before returning
return;
}
isRunning = YES;
// Do fun stuff here
isRunning = NO;
[theLock unlock];
}
// This method uses #synchronize
-(void)myMethod2
{
#synchronized(self)
{
if(isRunning == YES)
{
return;
}
isRunning = YES;
// Do stuff here.
isRunning = NO;
}
}
#end
Wow. That answer is correct, but way over-engineered. Just use #synchronized().
Foo.h:
#interface Foo
{
id expensiveResult;
}
- (void) bar;
#end
Foo.m:
#implementation Foo
- (void) bar
{
#synchronized(self) {
if (expensiveResult) return expensiveResult;
.... do expensive stuff here ....
expensiveResult = [theResult retain];
}
return expensiveResult;
}
#end
If you have multiple instances of Foo and want to guarantee exclusivity across all instances, create a global variable in +(void)initialize -- an NSString will do fine -- and #synchronized() on that.
However, your question raises a much more important question. In particular, there is never a case where the same method is going to be called twice simultaneously unless you quite explicitly configured your application to cause exactly that to happen.
The answer(s) provided sound more like a fix to a symptom and not a fix for the real problem.
Note: This is relying on expensiveResult being nil, which it will be as all iVars are nil on instantiation. Obviously, reset the ivar to nil if you want to recalculate.
simplest is to set a flag.
- (void)action {
if (flag_is_set == NO) {
flag_is_set = YES;
do stuff
flag_is_set = NO;
}
}
this is not 100% safe though as you may get some rare cases of interlocking.
If you can handle some sleeps on the thread, use a nslock
- (id)init {
theLock = [[NSLock alloc] init];
}
- (void)action {
[theLock lock];
doStuff
[theLock unlock];
}
When thread 2 comes to the lock call and thread 1 already has it, it will sit in the execution loop until the lock is released, then it will start again. If you have UI on this thread, you app will appear to freeze
Some of the given answers are acceptable solutions to the problem of multiple "producer" threads calling the same function at the same time but you might be better off figuring out why multiple threads are calling this same block of code at the same time. It could be that you are assigning this delegate to multiple event handlers or something like that. You have probably noticed that this is occurring because some shared state is being mangled or the output of the function is not correct for the "global" state at the end of the function. Putting a bandaid over the fact 2 threads are in a given function (when its clear that threading was not a primary concern when this was written) is not going to necessarily give you the right results. Threading is not trivial and shared state makes it very tricky to get right, make sure that you completely understand why this is occurring before just trying to patch over it.
That being said, if you do take the bandaid approach, its probably better to do one with a lock where every thread eventually gets to execute the function rather than having them bail out if the function is allready started because to the client code it would look like that long and "heavy-lifting" process has completed and they may check for the results.
If these calls are synchronized, so only one happens at a time, you can just have a variable on your class, called something like "initialized", which starts off false and is set when initialized:
if (!initialized) {
// handle delegated call
initialized = 1;
}
If the delegate is called from multiple threads, you need to put all this in a mutex block.
Here's how you can use objective-c locks as mutexes.
http://rosettacode.org/wiki/Mutex#Objective-C
Mutexes exist to allow mutually exclusive access to a certain block of code. Within the method you can do something like:
[methodLock lock]; //Blocks and waits until the lock is released
//...do stuff
[methodLock unlock]; //Releases the lock once the code has executed.
This will ensure that only one thread will be allowed within the //do stuff block of code.
EDIT: I read the question again; within the lock I'd check the flag to see if it's run (using a BOOL)
Use pthread_once() -- it was explicitly designed to do exactly this. The only problem is that the function you pass it can't take any arguments, so you have to use global variables to pass information to it.
If they are called at the exact same time, I guess they are called in threads?
What you can do is define a BOOL #property (called isRunning for example) with the attribute atomic (set by default). This way this property can be accessed safely from different threads, and then you can do something like:
if (isRunning)
return ;
isRunning = YES;
// ...
// Your code here
// ...
usRunning = NO;
You might also make sure that you are doing the right thing. If your method is called twice, maybe you're doing something wrong (or maybe it's normal, I don't know what you are doing ;))

Objective-C equivalent of Java's BlockingQueue?

I'm just getting into iPhone development after many years doing Java development. I'm looking for the Objective-C equivalent to Java's BlockingQueue. Is there something like that?
In case I'm going about things the wrong way, here's what I'm trying to achieve:
I want to display, one at a time, chunks of data pulled from a network server. To keep the user from noticing network lag, I want to always have a few chunks of data pre-fetched. In Java-land, I'd use a thread-safe queue between my fetching thread and my display thread.
Here's an implementation of a blocking queue with a queue and dequeue method. The expectation would be that one thread goes into a loop calling dequeueUnitOfWorkWaitingUntilDate: and processes units of work while a second thread is calling queueUnitOfWork:.
#interface MyBlockingQueue : NSObject {
NSMutableArray *queue;
NSConditionLock *queueLock;
}
- (id)dequeueUnitOfWorkWaitingUntilDate:(NSDate *)timeoutData;
- (void)queueUnitOfWork:(id)unitOfWork;
#end
enum {
kNoWorkQueued = 0,
kWorkQueued = 1
}
#implementation MyBlockingQueue
- (id)init {
if ((self = [super init])) {
queueLock = [[NSConditionLock alloc] initWithCondition:kNoWorkQueued];
workItems = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc {
[queueLock release];
[workItems release];
[super dealloc];
}
- (id)dequeueUnitOfWorkWaitingUntilDate:(NSDate *)timeoutDate {
id unitOfWork = nil;
if ([queueLock lockWhenCondition:kWorkQueued beforeDate:timeoutDate]) {
unitOfWork = [[[queue objectAtIndex:0] retain] autorelease];
[queue removeObjectAtIndex:0];
[queueLock unlockWithCondition:([workItems count] ? kWorkQueued : kNoWorkQueued)];
}
return unitOfWork;
}
- (void)queueUnitOfWork:(id)unitOfWork {
[queueLock lock];
[queue addObject:unitOfWork];
[queueLock unlockWithCondition:kWorkQueued];
}
#end
You can simply spin off an NSOperation and post a notification when the data has come back (finished loading). Take a look at Dave Dribin's blog post on concurrency with NSOperation that shows how to encapsulate an NSURLConnection session:
http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/
If you are not talking about accessing a web service or site where NSURLConnection is appropriate, you can instead use Cocoa Async Socket if it's straight TCP/IP or UDP:
http://code.google.com/p/cocoaasyncsocket/
Best Regards,
I don't think such a thing exists natively - you're probably going to have to write your own class that maintains a queue of network objects. Your header might look something like:
#interface ObjcBlockingQueue : NSObject {
// The objects that you're holding onto
NSArray *objects;
}
#property(nonatomic,retain) NSArray *objects;
- (ServerData *)getNextChunk;
Then you can implement getNextChunk to pop and return the top object off your objects array, and if [objects count] is less than a certain value, launch a thread to fetch some more objects (probably using NSURLConnection with ObjcBlockingQueue being the delegate). You can also have that thread/connection launched inside an overridden init method to prefill the queue.
You might also want to think about adding a
- (BOOL)isChunkAvailable;
method that will let your display thread know whether it can display something new right away or if it has to display a loading message. Depending on where you're displaying the data and how your app is structured, it may also be worth your while to make ObjcBlockingQueue a singleton class.