Contact

Please feel free to email me:

fraser@speirs.org

Search
My Stuff
Navigation
Thursday
Jul122007

Bare Strings Considered Harmful

FlickrExport is a pretty mature project now. Lots of things in the code that I once wasn't sure would last are now solid, tested and reliable. However, with age, software becomes interdependent and thus fragile. Some of the work I've been doing on FlickrExport 3 has been to formalise the relationships between various classes.

One of the problems that FlickrExport has is that it has a lot of threads. Because of a limitation in NSURLConnection - namely, that its asynchronous API only works when the runloop is in NSDefaultRunLoopMode - FlickrExport handles its own thread creation and uses NSURLConnection's synchronous API.

As a result, I spend a lot of time calling `-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:modes:]`. What's mildly (OK, *very*) annoying about this call is that it only lets you pass in one object. Consequently, one also spends a lot of time packing arguments into NSDictionary and unpacking them again on the other side. I criticise this method but I am, in fact, old enough to remember the days of Mac OS X 10.1 when it did not exist. Weighing up the pros and cons I'm happy to marshal and unmarshal objects all day long :-)

Anyway, I often use NSString as the key to these dictionaries. The trap for young players is this: if you find yourself writing `[myDict setObject: foo forKey @"theFoo"]`, stop and think carefully. Unless the locality of use of that key is within five lines of code of where you set it, I would argue that you're doing something wrong.

Why is it wrong? Two reasons. Firstly, if that dictionary is accessed from outside your class, you're leaking implementation details. You're no longer free to change the key to that object in that dictionary, unless you know the details of all the clients of that class everywhere. Secondly, your client classes critically depend on the spelling of a string - something that the compiler will not check for you.

FlickrExport had a number of places where one class would do something on a background thread, package up the arguments into an NSDictionary using bare strings as keys, and send that dictionary to another class in another thread.

What I've been spending time on today is defining constants for every possible key for every NSDictionary that is accessed outside of the class that creates it. I'm also defining a lot of constants for dictionaries that are passed around inside a single class. If your dictionary isn't used outside its class, you're at least not violating encapsulation but you are still at risk of simple typos causing obscure runtime errors.

I'm not quite at the point where I would argue that you should define constants for your KVO/KVC paths. However, I simply avoid referring to KVC paths more than one element deep in my code for precisely the reason that it can't be checked by the compiler. The only exception I make is calling `-mutableArrayValueForKey:` in order to do array manipulations in a way that is seen by KVO and Cocoa Bindings.

Daniel's suggestion of `@keycode(foo)` is tempting.

Reader Comments (3)

Think messaging! :-)

Then, think Higher Order Messaging: one object is enough if it's an NSInvocation, and construction NSInvocations is painless with a trampoline.

Slightly adapted from the paper at http://www.metaobject.com/Research.html :

[[anObject onMainThread] myMessage:firstArg withMore:stuff andEvenMore:stuff];

Dictionaries and the bare string(-keys) you rightly lament are often an indicator of missing or insufficient metaprogramming facilities.

July 13, 2007 | Unregistered CommenterMarcel Weiher

While it doesn't avoid the issue of bare strings, I was interested to discover recently that notifications posted using NSDistributedNotificationCenter are now (ie, post-10.3) delivered on the main thread. This obviates the need to use performSelectorOnMainThread:withObject:waitUntilDone:modes: and I dunno, it "smells" better to me.

That would leave you passing the dictionary as part of the NSNotification's userInfo which doesn't seem like much of a step forward but is a better fit with the Cocoa design than direct method calls.

July 16, 2007 | Unregistered CommenterBen Golding

Windows XP has Microsoft Office 2010 also been criticized Microsoft Office 2007 by some customers for Office 2010 security vulnerabilities, tight Office 2007 integration of applications like Internet Explorer 6 Office 2010 Microsoft and Windows Media Microsoft Office Player Let’s think for another MS office 2007 time. You take 200 customers and Microsoft outlook 2010 stop working with our Affiliate Program Office 2007 key, the reason is that you Microsoft outlook do not have enough time. Then you are able to Office 2007 download earn 4000 every year Outlook 2010! Versions with Service Pack 2, Service Pack 3, and download Office 2007 Internet Explorer 8 addressed Microsoft Office 2010 download some of these concerns. The Benefits of our Program Office 2010 download is written below: first, Our affiliate office 2010 trial program is FREE to take part Office 2010 key in .Then, You are able to earn on every purchase office 2010 pro of your customers. At the same time microsoft office 2010 trial, We have payouts office 2010 home – accept download Office 2010 a check monthly for office 2010 professional your sales.

June 2, 2011 | Unregistered CommenterOffice 2010
Editor Permission Required
You must have editing permission for this entry in order to post comments.