Ad

Our DNA is written in Swift
Jump

NSNotifications and Background Threads

I’m coming out of highly concentrated work (approx 87 hours) on my latest project. It’s an app that allows you to organize a betting pool for the upcoming FIFA World Cup.

The simplest method of communicating with our web-based API we found to be having the server send array or dictionary PLISTs which I could load and parse in a single line of code synchronously. So first I created all the API calls in synchronous blocking mode. When they where working I added a method by the same name prefixed with “async” and would have the blocking code executed on an NSOperationQueue.

If the synchronous method needed zero or one parameter then you can use NSInvocationOperation of calling it and have the queue work it off in the background. In some cases more than one parameter has to be passed. Here an NSInvocation has to constructed with multiple parameters, which I explained previously.

Once the API call is done processing it needs to tell the app about its result. This is done conveniently by sending NSNotifications. And in all the places in the UI where specific notifications should have an effect, you simply subscribe to the notifications by adding an observer for them to the default NSNotificationCenter. NSOperationQueue automatically uses multiple threads and takes care of the autorelease pool. So any operation might either run on the main thread or on a background thread.

Warning: Crash Ahead!

This causes a problem I have only ever seen happen on Simulator, so I’m not sure if it would also happen on the device. Generally you want the NSNotifications to be sent on the main thread as well, especially if they trigger UI activities like dismissing a modal login dialog. I don’t know if Apple will tweak NSNotificationCenter to send on the main thread in the future, but until they do, here’s my drop in solution.

The following code combo would cause a nasty crash if run on a background thread.

// in the background method to create a user
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:status] forKey:@"Status"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"DTBettingPoolUserCreated"object:niluserInfo:userInfo];

Subscribing to this notification would be a method to dismiss the modal login dialog, which most of the time it did appropriately.

[self dismissModalViewControllerAnimated:YES];

Sometimes, not always this would result in the following output:

2010-05-21 13:03:58.409 wcbettingpools[52251:6223] void WebThreadLockFromAnyThread(), 0x4857290:
    Obtaining the web lock from a thread other than the main thread or the web thread. UIKit
    should not be called from a secondary thread.
2010-05-21 13:03:58.409 wcbettingpools[52251:6223] bool _WebTryThreadLock(bool), 0x4857290: Tried
    to obtain the web lock from a thread other than the main thread or the web thread. This may be
    a result of calling to UIKit from a secondary thread. Crashing now...

Well, thankfully the crashing statement contains a hint to the error of our ways. “Calling to UIKit from a secondary thread” is precisely what this is doing. The NSOperation is on such a secondary thread, and the method we’re calling belongs to UIKit. Peeking at the top of our debugger also reveals that in fact we are not on the main thread.

So let’s not do that any more. The quick fix is to have default center perform the action postNotification on the main thread like this:

// post notification on main thread
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumbernumberWithInt:status] forKey:@"Status"];
NSNotification *note = [NSNotificationnotificationWithName:@"DTBettingPoolUserCreated"  object:html userInfo:userInfo];
[[NSNotificationCenter defaultCenter] performSelectorOnMainThread:@selector(postNotification:) withObject:note waitUntilDone:YES];

It works, but it’s ugly, and the compiler does not check for syntax errors in selectors. So we do the natural thing for a Cocoa Coder, we create a category extension to NSNotificationCenter.

NSNotificationCenter+MainThread.h

@interface NSNotificationCenter (MainThread)
 
- (void)postNotificationOnMainThread:(NSNotification *)notification;
- (void)postNotificationOnMainThreadName:(NSString *)aName object:(id)anObject;
- (void)postNotificationOnMainThreadName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
 
@end

NSNotificationCenter+MainThread.m

#import "NSNotificationCenter+MainThread.h"
 
@implementation NSNotificationCenter (MainThread)
 
- (void)postNotificationOnMainThread:(NSNotification *)notification
{
	[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:YES];
}
 
- (void)postNotificationOnMainThreadName:(NSString *)aName object:(id)anObject
{
	NSNotification *notification = [NSNotification notificationWithName:aName object:anObject];
	[self postNotificationOnMainThread:notification];
}
 
- (void)postNotificationOnMainThreadName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo
{
	NSNotification *notification = [NSNotification notificationWithName:aName object:anObject userInfo:aUserInfo];
	[self postNotificationOnMainThread:notification];
}
 
@end

With this you just replace every postNotificationName: with postNotificationOnMainThreadName: and don’t need to change anything else to safely send notifications on the main thread. That’s the kind of class you will want to have in your tool chest.

All the while I was assuming that NSNotificationCenter would be smart enough and “just work”, but I learned my lesson. These kinds of crashing bugs are sometimes hard to find, but teach you a great deal.


Categories: Recipes

10 Comments »

  1. Don’t you think that the most natural way of handling this kind of situations is to execute the UI-related code on the main thread inside the notification receiver? The effect would be the same but in this case we don’t need any additional categories. My thought is: If Apple wanted to post all the notifications on the main thread instead of the thread they were posted, then it would be done by default.

  2. Well with the approach you suggest you’d have to write a lot more code to force things like dismissModal…onto the main thread. I think Apple did not use the main thread per default because updating the UI is only one of many uses for notifications. Most other code would not care on which thread it runs.

  3. +1. Spot on – helped me out.

  4. agree with Talisman..i consider it the fault of the person who wrote the notification receiver!

  5. Great! Save me.

  6. Всем Доброе утро! Судя по ситуации на городских банях с задачей похудеть к лету половина человечества не справляется. Но это не беда. Вам поможет ягоды Годжи. Подробнее на сайте – http://gojiberry.tostlar.ru. Будьте стройны и счастливы!

  7. In the event you decided to get skilled help from dermatologist to your child, most likely you may be prescribed Lac-Hydrin, Bactrim or Erythromycin. These are the cells that over react to pollen or different allergens inflicting the allergy issues. In case you undergo from seasonal allergy symptoms, start your therapy a few weeks before your symptoms usually begin and continue through the allergy season. To detect meals allergy symptoms, physicians usually use pores and skin prick assessments or blood exams that measure levels of allergen-particular IgE (sIgE), a protein made by the immune system. Your physician will most likely prescribe allergy medication, which it’s best to take daily per the given instructions.

    She claims nasal sprays are more widespread than capsules in Europe (among allergy meds that’s). There’s a generic for Flonase now obtainable which is just nearly as good as the brand (fluticasone) so may wish to ask for that as an alternative when you’re at the MD office. Relating to allergy season, make peace with the flowers and trees – getting along with nature as an alternative of perceiving it because the enemy: Less stress, fewer allergy symptoms for the general population who shouldn’t have life-threatening allergic reactions. I threw away my allergy meds a decade in the past and am residing proof of balanced residing decreasing irritation.

    Why ought to I burden the health care system getting affirmation of a disease for which I already know the treatment. Are you in a special season – larger allergy season beforehand and at the time of this writing not (6 weeks is quite a little bit of time and much can happen then). FDA approval of APOQUEL relies on outcomes of two medical trials carried out within the United States which confirmed that APOQUEL was effective within the remedy of pruritus associated with allergic dermatitis and for the control of atopic dermatitis. In each studies, canine that remained on APOQUEL past one week skilled steady enchancment all through the course of the study.

    One Alzheimer’s research doctor, Dr. Simon Ridley, famous that the examine added to current proof that there is a small elevated risk of dementia, but the results don’t tell us that these medicine cause the condition.” The lead writer of the research famous that nobody should stop taking their medications with out discussing it with their doctors. A corn allergy or intolerance is an disagreeable reaction to any corn derivative.

    Some allergy medicine is on the market as pictures, and these often assist your body to adjust to its personal reactions to allergies so that you just no longer have the signs. After all, in case you’ve been prescribed allergy medication or have severe allergic reactions, it is crucial that you simply take your meds and call emergency companies when you have an allergy assault that retains you from respiratory. I’ve all the time been hypomanic till the stress of adopting special needs teens brought about me to have to start out taking meds. I do Benedryl at the first sign of a significant allergy attack (even if it means I am going to get sleepy, forcing a change in plans).

    Allergen-particular immunotherapy has been demonstrated to be more economical and improves the patient’s quality of life more effectively than commonplace allergy medicines. Competes with histamine for H1 receptors in GI tract, blood vessels, and respiratory tract, reducing hypersensitivity reactions. Presently, azelastine and olopatadine are the only brokers available in the United States. If desired, could also be used with different medicines, together with other allergy medicines.

    If you’ll be able to take two teaspoons of native raw honey a day two months earlier than your allergy season begins, you’ll be able to keep off lots of your allergy symptoms. I am not an allergy sufferer however still it seems a superb thing to do. Great hub, very informative and I’ll move this on to Bev who does have allergies. I’m going to start to use honey as I’m experiencing some allergy as a result of pollen count.

    Blood testing for canine allergic reactions generally is a helpful screening methodology to slim the vary of potential causes for the irritated skin. The tests are non-invasive and are generally used for young canine, canines that cannot tolerate corticosteroids and for show canine with hair that can’t be shaved for different checks. Essentially the most correct and thorough test for allergic reactions in canine is the intradermal pores and skin testing. Studying the results of pores and skin assessments accurately can lead to identification of the reason for the allergy to be as high as seventy five%. For allergy sufferers, April Fools? Day means one thing higher than an excellent chuckle.

    I have seen repeatedly that when my clients scale back their baseline reactivity by cleaning up their diets, increasing hydration, and supporting the liver in its detox duties, that allergy signs they thought they have been caught with diminish, sometimes drastically. Avoid the 3 common suspects: during your allergy challenge season, lower out dairy (which can visit here be mucus forming), and scale back or get rid of sugar and wheat. If your allergies are extreme, you could want to contemplate supplementation with these nutrients for 2-three months leading as much as allergy season, and through. If you’re in the midst of allergy season, start taking the local raw honey instantly.

    Low cost pet meds are definitely an possibility for many who wish to have the upper dander sort breeds. For those of you who actually wish to eradicate allergies to pets, the perfect wager is to go to your Medical Physician or allergist and begin getting allergy shots. Bear in mind how allergy medicine works when deciding on your remedy methodology. My morning routine: I measure out all the meds and put them in my little basket.

  8. Здравствуйте уважаемые!
    Предлагаем Вам
    Дробилка шредерная ИШМ-400 , Дробилка для пенопласта
    Дробилка для синтепона Click here