A friend of mine at Xcoders told me about threading issues with NSNotificationCenter and KVO. In my own code I always post notifications on the main thread and do any KVO-triggering on the main thread (for precisely the reasons he spells out) — so it’s not an issue I’ve run into. But it’s something you should be aware of.
My friend elaborated via email. Below is his email (edited for typography and typos only):
* * *
In most ways that matter NSNotificationCenter is thread safe. You can add/remove observers from any thread and you can post notifications from any thread. You’re on the hook for the thread safety of your observer/selector or block handler, but that’s a pretty reasonable way for the API to work.
Here’s a pretty normal pattern for using notification center:
self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(prompt:) name:@"PromptUserToRateApp" object:];
- (void)prompt:(NSNotification *)note
// Do something async
[[NSNotificationCenter defaultCenter] removeObserver:self];
and then somewhere else in your code:
[[NSNotificationCenter defaultCenter] postNotificationName:
This is a perfectly safe thing to do if all those things are happening on the same thread OR if you can guarantee that dealloc will run on the same thread as your -postNotification: calls (or doesn’t run like in the case of singletons.)
Where it gets hinky is when -postNotification: can run on any thread (and therefore so can dealloc because -postNotification: will retain/autorelease it before running.)
Here’s the bug:
Thread 1 calls release taking retainCount down to 0 meaning the object will be dealloced. Your object is dead, is just doesn’t know it yet and there’s no coming back.
Thread 2 comes in and posts a notification, for this case let’s assume synchronously since that’s the common case with the observer/selector API. Observer is retained before calling because notification center keeps an unretained reference to observer and wants to make sure the object is alive. Thing is, you can call retain on an object that’s already in dealloc and that doesn’t stop dealloc from finishing and turning that object into a zombie. So now thread 2 is calling into -prompt: and self is in the middle of becoming garbage so nothing you can do in -prompt: will be safe.
Thread 1 gets into dealloc, the observer gets removed and self becomes garbage rendering anything async you did in -prompt: very dangerous. (Doesn’t even have to be async, but that’s the most pronounced case for this problem.)
This same problem manifests with KVO in a nearly identical way and also with notification centers block based API, although in that case it’s actually the internal __NSObserver object that can end up as the bad object being referenced and there’s the added fact that the observer gets retained and then the block gets scheduled asynchronously so if the scheduling hits while in dealloc, the block will almost certainly run after dealloc has finished.
So what do I do?
There are a few options:
Serialization - Run everything on one thread, not exactly elegant, but it does take a lot of the guess work out. This is actually pretty normal if you’re handling notifications in a view controller posted by system API that promises to run on the main thread. Although, this can fall down pretty easily though because making sure dealloc runs on a specific thread when blocks and autorelease pools exist can be incredibly hard.
Block based API - In practice it’s much harder to hit this issue with the block based API due to the lifetime of the observer object it gives back, but it’s definitely not impossible with some well placed autorelease pools and the block based API is also a snake pit of subtle bugs for many developers.
Objects with safe lifetimes - This issue doesn’t present at all if your target is for example a singleton. Not that I’m suggesting you use more singletons, but if you already have a data controller singleton, it’s a perfectly safe target for threaded notifications.
Don’t use notification center - Ya know what’s great? Weak delegates. The self zeroing weak references in ARC are great and one behavior they offer that’s incredibly useful is that they return nil once an object is going to be dealloced, even before dealloc runs.
This code is totally thread safe:
id<MyProtocol> delegate = self.delegate;
if ([delegate respondsToSelector:
It’s not strictly required that you use the local ivar, but it’s a good idea since it guarantees that if you get a value back, it will be retained (under ARC) into the local strong variable and live at least through the scope of calling the delegate method.
I’ve always liked delegates. These days I like them even more.
P.S. For people grumbling about how notification center should use weak refs internally, there’s some merit to that, but the unexpected side effects of when weak refs zero can lead to some oddball bugs like if there are multiple observers that are the same except they are registered with different objects (for filtering purposes) and then they all go to zero and you have to decide which one to remove when -removeObserver: is called. It’s not as straightforward as it might seem.
WinterFest 2013 is the “festival of artisanal software for writers.” Tinderbox, Scrivener, Scapple, DEVONthink Pro Office, and Nisus Write Pro are on sale for the holidays.
App Santa is “award-winning apps, up to 60% off for Christmas.”
Vesper is $2.99 (regularly $4.99). A bunch of other cool apps are on sale too: Day One, Tweetbot, 1Password, Clear+, PCalc, and more.
I’m so pleased. I don’t have any business interest in this sale — just the personal satisfaction of knowing that software I helped create is going to a great home.
I use Glassboard every day. It’s the main way Q Branch communicates. I use it with my family, with the local Xcoders group, and with other small projects.
This acquisition marks a personal moment: everything I brought to NewsGator, or created while there, has been passed off to another company. None of my apps remain. They’ve moved to Black Pixel, Push.io, Red Sweater, and now Second Gear.
We just posted Q Branch Standard Kit — QSKit, for short — to GitHub.
It’s a bunch of categories and utilities that we find useful in multiple apps (both Mac and iOS). Nothing earth-shaking or high-tech — just solid stuff. With tests.
Consider it an early Christmas present from us to the community that’s given us so much.
(This is one of the perks of my return to indie life: I can release open source software again. I’m so glad.)
A few things are interesting (at least to me) about this list:
Only OmniFocus and Vesper were recognized as iOS apps. The rest are on the Mac list. We love Mac software.
Only The Omni Group and Gus are purely Washington state. My co-workers are in New York City and Philadelphia; Chris’s co-worker Guy is in Montreal; and Black Pixel, though Seattle-based, has remote workers everywhere. (Probably even in your town.)
If you wanted to stretch definitions a bit, you might include Delicious Library, which originated in Seattle and thrived here till Wil ran away to San Francisco. Library, also a Mac app, would not look out-of-place in the list.
These are all productivity apps.
It’s possible that there are other Seattle-made apps on the list, and it’s possible that some of those are games. But, if that’s true, then those game-makers aren’t joining the Cocoa community here.
We used to write games here. I’m sure we still do. But as a community we are, apparently, better at productivity apps. Mac apps especially.
(I offer no theories. Not even the easy one that blames it on the rain, because you’d think people make games indoors too.)
The promise of Twitter is that it’s live people, but the reality is that it’s Live People Magazine.
Justin Bieber has 47,751,842 followers at this writing. A recent tweet — “Listening to music. #Journals #7days” — has 40,164 retweets and 28,504 favorites. Replies include “@justinbieber love u” and “@justinbieber i love youuuuu.”
Replies also include people begging to be followed back, which is the saddest thing I’ve seen all day. (Admittedly I haven’t been awake that long.)
You might say that’s not fair, but look at the numbers. This is what Twitter is. People Magazine has more substance.
If I go to the website I can see “What’s happening now, tailored for you.” And I see tweets from ESPN (don’t care), Variety (don’t care), Gizmodo (don’t care), and so on.
(I just clicked on a few trending topics, something I never do. I’m reminded why. I can’t bear to describe what I saw.)
Twitter’s job, it’s only job, is promotion. In return it gives people the illusions of information and human connection in 140-character-bites, which is the least — I mean it — the least it could do.
Well, now you’ll see those accounts in your mobile timeline, where you didn’t before. Also, advertisers will be able to add a geotargeted call-to-action message to entice you into following them. This will affect the 76 percent of Twitter users who access the site from their smartphones…
It’s worth noting that Twitter only makes money if users click on Promoted Accounts — the same applies to Sponsored Tweets — so making those ads as engaging as possible is the social network’s M.O.
Every frog likes the warmer water. It feels like that first summer and those carefree tadpole days.
Last night at Xcoders people asked me about the enterprise app I mentioned yesterday.
Here’s the story, condensed as much as possible:
In 2005 NetNewsWire was acquired by NewsGator, an RSS reader company with a deployed sync platform. I went along with NetNewsWire to that company. I continued to work on NetNewsWire for years.
Though that company started out as an RSS reader company, it later turned off its RSS reader software as it evolved into an enterprise software company that makes a business-oriented Twitter/Facebook-like-thing (plus extras) that runs behind the firewall. (Called Social Sites.)
I think that’s a pretty a good business. I have zero interest in it personally, but it makes sense, and I believe the company made smart choices, even though that meant it was a very different company from the one I joined.
Though the company had become focussed (quite rightly) on their main enterprise product, I remained working on consumer apps: NetNewsWire, then TapLynx and then Glassboard.
We sold TapLynx and NetNewsWire to other companies. That left me working on Glassboard, in a small spin-off company of six people called Sepia Labs. Sepia Labs was owned by NewsGator, and it had zero employees, but it actually existed as a company.
In all those years I had not been asked to work on the enterprise software. I didn’t want to.
But that changed in late 2012 — mainly because leadership really liked the work we’d done on Glassboard, and they wanted the same team to redo the iOS and Android clients for their enterprise app.
I could have said no, but I would have had to resign right then, and I was unprepared. So I said yes, knowing that I’d have some months to work things out, to either make peace with this somehow or move on.
But that meant actually working on software I didn’t care about or even like. (Not because it’s inherently bad, I should point out — it’s just not the kind of thing I like.)
We worked on it much the same way we had worked on Glassboard: Nick Bradbury did wireframes and I did the Photoshop mockups and assets.
The difference was that I didn’t write any code, where I had written 75% (or so) of Glassboard for iOS. Nick Harris wrote the iOS app and Nick Bradbury wrote the Android version. I was a designer only. (Which is like saying I tried enterprise software but didn’t inhale, I realize.)
NewsGator had treated me extremely well for many years. But a series of rational decisions on everyone’s part (mine and the company’s) meant that I was suddenly working on enterprise software, and I came to realize that I needed a change. There was no making peace with staying.
It was time to come home to indie life, where I’m happiest, where I do my best work.
* * *
I’m never going to be a manager. The fun of this industry, for me, is in making things directly, in getting my hands covered with clay.
And I’m not, at age 45, the best I’m ever going to be. That’s still in the future. But I’m getting closer. My peak isn’t 20 or 30 years from now: ten years is more likely.
As a teenager I read “Seymour: An Introduction” by J.D. Salinger. In that story Buddy, the narrator and a writer, had given his older brother Seymour a new story to read. Seymour liked it well enough as craft, but it fell short of being Buddy-worthy.
Seymour wrote to Buddy, “Keep me up till five only because all your stars are out, and for no other reason.”
I’ve kept that in my head every since. The work that happens when all my stars are out is the work worth doing.
* * *
More from Seymour, just because I like it:
Were most of your stars out? Were you busy writing your heart out? If only you knew how easy it would be for you to say yes to both questions. If only you’d remember before ever you sit down to write that you’ve been a reader long before you were ever a writer. You simply fix that fact in your mind, then sit very still and ask yourself, as a reader, what piece of writing in all the world Buddy Glass would most want to read if he had his heart’s choice. The next step is terrible, but so simple I can hardly believe it as I write it. You just sit down shamelessly and write the thing yourself.
We formed Q Branch on 12/12/12. We wanted an easy-to-remember date.
I didn’t start working on Vesper until the beginning of February 2013 — I waited until I was finished with my then-current job. Though I initially conceived of Q Branch as a side project, it took me almost no time to change my mind and go full-time. (Then I had to give a reasonable amount of notice and wait.) That was one of the best decisions of my career.
A year ago I was a designer for an enterprise app I didn’t care about — or even like in the least tiny bit — and which you’ve never seen or heard of. That’s no way to live.
And now I work with my friends on Vesper. That’s the way to live.
These days we all pull-to-refresh for a living.
Alexis Madrigal writes in The Atlantic that 2013 may be the year “the stream” crested:
The great irony is that we got what we wanted from the stream: a way to read and watch outside the editorial control of editors, old Yahoo-style cataloging, and Google bots. But when the order of the media cosmos was annihilated, freedom did not rush into the vacuum, but an emergent order with its own logic. We discovered that the stream introduced its own kinds of compulsions and controls. Faster! More! Faster! More! Faster! More!
I’m not on Facebook, LinkedIn, Instagram, or SnapChat. I’m on Twitter.
Twitter used to be fun, but it’s not fun anymore and it’s never going to be fun again.
Years ago Twitter was the street corner where we all hung out. Craig Hockenberry and Loren Brichter — Twitter app developers — would pull up on their skateboards and show us cool new tricks.
We felt like it wasn’t just a thing-to-do: we felt like we were on to something. There was something new to discover.
It took years for me to learn that the feeling of being on to something is a pretty easy illusion to create. I stopped reading Twitter several months ago and haven’t missed it. I still pay attention to mentions and sometimes I reply — because I don’t want to be a jerk, and I think it’s important for people who make things to be accessible.
The 140-character stream is where things not worth saying, and not worth reading, thrive. It’s where things actually worth saying get over-simplified and then get lost, if they get said at all.