I\'ve been pondering over this question for a while now...
On the one hand, Interface Builder offers a really easy way to design the interface and wire the elements
It depends on your preference.
I prefer to write it in code.
IB is great for prototyping and browsing object capabilities and appearances (I am not a graphic designer), though I think it is easiest to just write it in code once the prototype exists if you have any intention of maintaining or reusing it.
My recommendation: Write highly reusable and stable code libraries, and use IB primarily for prototyping and one-offs.
Responses:
Sbrocket: I'm curious as to why you assert that circular references are more likely to occur as a result of using NIBs.
Hi Sbrocket: I'll start by saying I've used Interface Builder since the Project Builder days (Xcode's predecessor).
Lack of reliable structured ownership, identity, and initialization. I don't want ivars to be IB connections because it makes many classes difficult to use beyond 'the current context', In other words, it ties the code to the resource (more often than ideally). Since you can't define initialization order or define initializers or additional initialization arguments in IB, you must then make the objects know about each other, creating circular dependencies and references.
Sbrocket: or why lazy initialization (assuming that's in fact what you're referring to) is so scary when its relatively easy (or in fact automatic in many cases) to ensure that the object is initialized and connected.
Re: scary I was not talking about lazy initialization. I was talking about deferred and ambiguous initialization order.
Nib initialization is semi-ordered. The actual order/process may vary, and this cannot be used reliably within reusable introspective programs... again, you'd end up writing too much code which is fragile, impossible to reuse, can never be assured to behave predictably, and must always validate state (yet another entry for circular dependence). If it is not a one-off implementation, why bother with the complications?
This approach to programming is chaotic and the implementations must (in turn) be prepared to handle anything at anytime. It is one thing to guard yourself from crashes, but to write defensive, production level code in this context... no way.
It is far easier to write a consistent program which initialization determines the validity in context, which the implementations can then know (if initialized) that the object is generally prepared to be used. Special-case complexity is minimized. Many such designs fall apart as program complexity increases, while library writers add layers upon layers of 'protective measures' just to keep gears moving - threading is a great entry for such heisenbugs. Unnecessary ambiguities are unwelcome in reusable production level code; humans shouldn't have to cross reference all of a program's special cases, and the complexities concerning defined behavior and special cases only spread or are ignored (assuming they are properly tracked and documented, which is more combined effort than writing it properly from the start). I think we can all agree that onerous interfaces and implementations should be avoided.
Sbrocket: I'd also be interested to see some hard numbers that show that NIB loading is slower - of course, it would seem to make sense at first thought, but we're always such bad predictors of performance bottlenecks without some hard testing.
I never said (explicitly) that it was slower :)
Ok, in seriousness, NIB unarchiving was (for me) a surprisingly slow process, though our ideas of slow and unarchiving times can vary dramatically.
Example: I had a document based app, and the nib loading was several times slower than the document loading, when document sizes were several times the nib size. Moving the implementation to code made the process much faster. Once it was on code and I had control of initialization order, I removed multiple multithreading complexities (checkpoints, locks, race condition entries, etc), which made document loading even faster.
Now that you have an explicit answer, I'll remind you that you have all the tools you need to measure performance.
Remember that performance analysis and enhancements are learned.