Prior to Apple acquiring NeXT, Objective-C had had relatively little added to it since it became a fully fledge language rather than simply a C preprocessor back in the 80s. About the only thing added for many years after Apple acquired NeXT was the @try…@catch…@finally exception syntax.
Then in 2007 Apple released Leopard and with it Objective-C 2.0 and the modern runtime. This added features such as properties, fast enumeration, class extensions and garbage collection and improved areas such as protocols, while making the runtime far more flexible and less fragile to change. Last year with Snow Leopard, Apple added blocks and associative storage to the language in what can sort of be thought of as Objective-C 2.1.
At WWDC Apple announced a few more features, which I personally think of as Objective-C 2.2. These are "@synthesize by default" and "declare ivars in class extensions". These are features that I have wanted for quite a while and I am sure a lot of other Objective-C developers have wanted. So what are they and how do you get them?
To get them there are two requirements:
If you fulfil those requirements then you're almost able to use them. All that is left to do is add these two flags to your "Other C Flags" build setting:
So now we're all set up, what the hell are these features?
NB: This feature is no longer available and so should not be used. It may re-appear at some point but in the mean time we sadly have to write our @synthesize statements. I've left the section in for reference if/when it comes back
With the addition of properties, Apple was able to remove a lot of boilerplate code from our classes. If you are using the legacy runtime then you are able to write code like this:
==========MyClass.h==========
@interface MyClass {
NSString *foo;
}
@property (copy) NSString *foo;
@end
==========MyClass.m==========
@implementation MyClass
@synthesize foo;
@end
It is a lot cleaner than what you had to write pre Obj-C 2.0, but it still has a lot of stuff to write. If you are using the modern runtime (ie are writing an iOS or 64 bit only Mac app) then you can get rid of the instance variable:
==========MyClass.h==========
@interface MyClass {}
@property (copy) NSString *foo;
@end
==========MyClass.m==========
@implementation MyClass
@synthesize foo;
@end
That's a bit cleaner, we're only having to sort out our property in two places rather than three, but it's still one too many. 95% of the time, you just want to synthesise the methods and instance variable and so the vast majority of property code in your implementation is the same. Well as you can probably guess, "@synthesize by default" means that this is done for you by the compiler by default. If you want to override it with an @dynamic statement or link it to a different instance variable you can, but for the rest of the time you can reduce your code to this:
==========MyClass.h==========
@interface MyClass {}
@property (copy) NSString *foo;
@end
==========MyClass.m==========
@implementation MyClass
@end
There is one slight gotcha with this. Due to what seems to be a compiler bug, you will get an error if you try to directly access the synthesised instance variable. Unfortunately the only ways to fix this are to either add @synthesize, add the instance variable or only access it via the property methods.
[Update] It seems that this isn't a bug but is instead expected behaviour. The @synthesize methods are generated at the end of the class if you don't specify them explicitly, as the compiler can't tell if the properties need to be default synthesised until it has got to the end of the implementation.
[Update 2] And now it seems the LLVM/Clang team are going to try and work around this and get it working as you would expect. Three cheers for the LLVM/Clang team!
So, we have got rid of the instance variables for our properties, but these are public anyway, it's not that big a deal if developers can see them in the header. However, what is left are the private instance variables, the ones only used internally in a class. We can hide methods we don't want as our public interface in our implementation file, but not our instance variables. Instead we end up with this:
==========MyClass.h==========
@interface MyClass {
id internal1;
id internal2;
}
@end
==========MyClass.m==========
@interface MyClass ()
- (void)internalMethod;
@end
@implementation MyClass
- (void)internalMethod {
NSLog(@"%@ %@", internal1, internal2);
}
@end
Thanks to Objective-C 2.0 and class extensions we can put our internal method declaration into our .m file and also have the compiler check that it is implemented and warn us if it isn't (unlike if we added a simple category). What we haven't been able to do is do the same for our instance variables. Well we can now, so our code can now look like this:
==========MyClass.h==========
@interface MyClass
@end
==========MyClass.m==========
@interface MyClass () {
id internal1;
id internal2;
}
- (void)internalMethod;
@end
@implementation MyClass
- (void)internalMethod {
NSLog(@"%@ %@", internal1, internal2);
}
@end
Our internal instance variables really are internal now, which makes the header effectively become purely our public interface. And if you are feeling really crazy, you can have multiple class extensions and maybe just put them in the @implementation:
==========MyClass.h==========
@interface MyClass
@end
==========MyClass.m==========
@interface MyClass () {
id internal1;
}
- (void)internalMethod;
@end
@interface MyClass () {
id internal2;
}
@end
@implementation MyClass {
id internal3;
}
- (void)internalMethod {
NSLog(@"%@ %@", internal1, internal2, internal3);
}
@end
These may only seem like small enhancements, but they help you reduce the code you need to write and make that which you do much neater. It is little enhancements like this that keep trickling out that makes the life of an Objective-C developer that much easier.
A while back I wrote a post on how I was pushing towards making my apps much more manageable, by separating my once monolithic app delegates and nibs into various view and window controllers. Yesterday Justin Williams wrote a post on his blog about Getting Started with Core Data, Bindings and NSViewController.
Cocoa has changed a lot over the years. I started programming on 10.3, when Xcode was a version 1.0 and Bindings, KVO and KVC were the new hotness. Over subsequent releases we gained Core Data, Objective-C 2.0, NSViewController, Garbage Collection and much more. I strongly believe that any modern Cocoa app should be using Core Data, Objective-C 2.0, Garbage Collection and NSViewController. Bindings should also be used where appropriate (I'll define where I think this is later).
Justin's post included a project he'd worked on, implementing core data tutorial application from CocoaDevCentral using several window and view controllers rather than one monolithic class and nib. The way he built his version was quite interesting, as it was differently to how I would have approached the task. As it was a relatively simple project, I thought it would be of benefit to some to provide an alternate way of building the same app. I don't think there has been two Cocoa developers giving two different ways of implementing an entire app before.
You can download the source for my version here. I also recommend downloading Justin's version. I'll first outline how Justin's implementation works and then go into how my implementation works and how it differs from Justin's.
But first it would make sense to outline the application. It is a simple blogging app. It consists of a main window containing a splitview. On the left is a list of posts, with an add button below. On the right are the details of the current post: the title, author, category and body. The author and category are chosen from a list which can be edited by clicking the edit button next to the field. This brings up a panel allowing editing of the author and category lists.
The data model is as shown below:

Justin has structured the application as 3 window controllers, 2 view controllers and the app delegate:
And that is all there is to Justin's implementation. It is very simple and most of the processing is pushed off to Core Data and NSArrayController.
I built my implementation with the same structure as my 3 existing apps. Rather than relying on core data and bindings completely, I use KVO manually and have a model controller that wraps around core data. I have a similar set up in terms of controllers: 3 window controllers, 2 view controllers and the app delegate. But I also have 9 extra classes, my model controller, 2 classes to simplify core data and 6 model classes generated by MOGenerator.
The following two classes I group together as M3CoreData. They are classes I've built that make CoreData cleaner and simpler to access.
And finally there are the 6 classes generated by MOGenerator. I've learned to swear by MOGenerator for my core data applications, it is removes all the hassle that you would otherwise have if you used Xcode's built in tool for generating model classes for core data entities. The only change from the generated code is an awakeFromInsert method in M3Post that sets the creation date.
One thing I like to do is abuse the responder chain (please don't call the police!). In larger applications I make sure every view and window controller on screen is in the responder chain. This has the advantage of being able to put methods where they belong, rather than where you can access them. For example, the newPost: method is in the window controller. In some of my apps I have it in the side bar controller, because that is all that cares about adding a post.
You can then connect you actions to the first responder proxy in the NIB. It will traverse the responder chain and find the appropriate class and then invoke the method. You can then control whether the method can be invoked by overriding respondsToSelector, which will give you menu validation control.
This is how the editAuthors: and editCategories: methods in the app delegate are called. The buttons in the details view are connected to these methods via the first responder proxy. As the app delegate is in the responder chain it will be the one receiving the methods (as nothing else futher up the chain implements them).
Bindings are a contentious issue. Some people love them, some people hate them. The fact is that they are incredibly useful and can save a LOT of code. To give one example, the new inline inspector in CCP 1.4 was initially all handled in code. Unfortunately this required a lot of logic for handling no selection, multiple selections etc. In the end I just replaced the code with bindings to an NSArrayController and managed to delete around 100-150 lines of code.
But bindings aren't useful in all cases. Over the years I've kept changing how I use bindings. I used to use them everywhere, then went through a phase where I didn't use them at all, but have now settled on a good middle ground, where I use them where they work best. So where is that?
There are a lot of people who avoid some of the new technology in Cocoa. Some don't like Core Data because it seems like voodoo (if you learn a little bit more you'll actually find that it is quite simple, yet incredibly powerful) and some dislike Garbage Collection because of experiences with other garbage collectors (in reality the GC in Obj-C not only saves you the pain of memory management but also of threading, while also potentially being faster than a retain/release system).
You should always be looking at the new technology that comes in each release of Cocoa, most of it can save you 100s, if not 1000s of lines of code if you can adopt it. It can also make the code you do have much easier to manage. It seems odd that most people would agree it is insane to write and use an alternative to something like NSTextView, yet will write and use an alternative to some more modern technology in Cocoa.
As with many of my blog posts, it is often a tweet or another blog post that made me want to write my thoughts. In this case it is both:
Just accidentally blew away 16 files' & days' worth of work with hg. Looked up, TIme Machine had just finished. Lost < 1 min. of work.
That tweet prompted Wolf Rentzsch to write this post about how Time Machine is your version control "safety net". To me both of these are shocking. It seems that the tweeted mishap may have been user error, but it made me look into how the various user interfaces help protect the user.
For a long while I was opposed to VCSs, mostly due to faffing around with subversion and getting nowhere. With DVCSs I've become an addict. The issue is that DVCSs also try to be clever. Their primary goal is to protect you from yourself, to make sure your code and its history are safe. Essentially your commit history should be like a stack. 99% of the time you push onto the stack, rarely you need to pop off a stack. You can read the contents of the stack as you want. But you shouldn't be able to modify the internals of the stack.
This is why I consider the many rebase plugins/commands in DVCSs to be harmful. I feel that rebase should be viewed as a mixture of goto, premature optimisation and Jeremy Kyle all rolled into one ie don't touch it unless you know what you're doing and are wearing many layers of protection, and even then it probably isn't such a good idea. Some people swear by rebase, but I feel that you shouldn't be messing with what should be treated as sacred.
This is where we get onto UI. I've never really given much thought to command line UIs, but comparing git, Mercurial and Bazaar I've found subtle differences in the UI that make it harder or easier for a user to perform a destructive action. These really fall into 3 categories: confirmations, making it hard to destroy and separating destructive actions.
In the case of the tweet at the start, I looked into the command that was performed: hg update -C . It offers no confirmation dialogue, it just cleans out the items that have changed. It doesn't make it hard to destroy changes and it is a one character option which means it is easy to do. I'm not sure about git but the equivalent in Bazaar would be bzr revert --no-backup. Of course there's no real reason to run --no-backup, it helps save your arse just in case and cleaning it up is just a case of bzr clean-tree --detritus (which lists the files to be deleted and asks for a confirmation).
One of the other examples is from the blog post. git branch -d abranch will delete the branch called abranch. Now to me this seems incredibly dangerous as there isn't any confirmation given. Occasionally I've seen warnings to use the uppercase -D option if changes aren't merged into the parent, but sometimes even those may not appear. If you're doing something like deleting a branch then it should be made harder to do. Really it should be git branch --delete-branch abranch and then ask you to confirm the delete.
Destructive actions should really be moved out into other commands if possible. bzr has 2 such commands: uncommit and clean-tree. Uncommit and clean-tree both list the items that will be removed and ask you to confirm. This makes the user double check what they're doing to confirm what they are doing. Now these commands could be moved into other commands. Uncommit could be made into bzr commit -d, but by separating them out you are making the user think that this is a different thing and making it harder for them.
It does seem very hypocritical, when most of UI design is a push to make life easier for a user, to advocate making it harder. But as odd as it may seem, making something harder may make it more usable. Now by harder I don't mean make a series of convoluted steps that require an animal sacrifice. I mean add an extra step to any potentially dangerous action. Tell the user exactly what the result of the action will be and ask them to confirm it.
Obviously you should provide undo when possible, but sometimes it isn't. Think about where in your UI you place these actions and consider whether you need them there at all. Don't put a 'wipe library' button right next to one of the most commonly used buttons in your UI, and no matter where you put it, if you can't offer an undo then tell the user exactly what you will do and make them confirm. Force them to pay attention to what they are doing. They'll thank you for it, even if it is just by not complaining to you (or worse to the internet) about how your software lost their data without warning.
At NSConference Dave Dribin made the following statement in a slide:
Delegates are preferable to Notifications which are preferable to KVO
Now this caused a bit of a murmur on Twitter, as it was taken as "KVO is bad". As this is an important topic and not one that can easily fit into 140 characters I thought I would write a post to outline my rules for when to use each technology and why use them where I do.
One of the main reasons delegates were listed as the most preferable is that they provide the least 'magic' way of communicating between objects while keeping them loosely coupled. It sends the message directly to the object and you can see what method is being run. As such it makes your code more self explanatory. So whenever you have a 1 to 1 relationship between two classes, opt for delegation over notification.
Notifications should really be used wherever you would use a delegate, but need to communicate with any number of objects. They should really be thought of as 1 to many delegates. Quite often in Cocoa you will see a case where there is a notification and a delegate method for the same event (eg change of selection in a table view). These are cases where 80% of the time you just need a 1 to 1 relationship, but occasionally do need a 1 to many relationship. You will rarely encounter this in your own code, unless you are building a class for use in multiple apps.
This is where I have found KVO to be the most powerful. You need to keep various UI elements in sync with your data model. Changing the value of the model from one view should also update the value in other views. KVO was built for exactly this situation and as such requires much less code than delegation and notifications.
To achieve the same effect with delegation or notifications you would have to add delegate methods or post a notification in each setter method of each model object. This obviously is a lot of code that needs to be written. Code that could have bugs and code that makes your source more cluttered. KVO of a value in an object requires just one line of code and the implementation of one method. And if you use bindings then it is actually no code at all.
I'll start with the exception to this: if you have multiple callback options then use delegates (eg NSURLConnection). But the vast majority of asynchronous operations need just a single callback. In these cases, if you are using Mac OS X 10.6, then you should be using blocks instead of delegates. Blocks reduce the layer of indirection in your source by putting the call back information inline with the invocation of the method.
The next two rules aren't quite rules of communication, but are relevant to the discussion at hand.
This should be pretty obvious. If something in your code isn't explicitly clear from the code itself then comment it. If you are sending off a notification say why you are sending it off, so you can get an idea of what it is doing elsewhere in the application.
There is no such thing as magic in programming, simply things we don't fully understand. If notifications, delegation, KVO or anything else seems like magic, then read up the documentation on it or ask a developer experienced in that area to explain how it works. When you find out how they work you realise that what seems like magic is fundamentally a very simple process.
Ultimately, what Dave said was right for some scenarios. Each technology has its use case and you should only use it where it is needed. You should always aim for the smallest amount of indirection in your code while still retaining loose coupling of classes. KVO and notifications are necessary in some occasions (unless you want to go crazy with delegation) but they should only be used when they are needed.