NSNotification's work very well for objects you want to have loosely coupled. In a Cocoa/iPhone context, that means no references between them, mostly.
In the controller that may receive the message:
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(doTheThing:) name: @"MessageBetweenControllers" object: nil];
In the controller that needs to send the message:
NSDictionary *dict = [NSDictionary dictionaryWithObject: <some object> forKey: @"key"];
[[NSNotificationCenter defaultCenter] postNotificationName: @"MessageBetweenControllers" object: self userInfo: dict];
The example above is just a template (for example, the NSDictionary bit is optional), but it shows the mechanism. Read the documentation on NSNotification and NSNotificationCenter to get the details.
This is not purely theoretical. It is the primary method I use for inter-object communication in my three published apps and my new one as well. The overhead for the notifications in miniscule.
Two gotchas: Make sure you only ever addObserver once per message -- the NSNotificationCenter does not cull duplicates; if you insert the same observer twice, it will receive the message twice. Also, make sure you do removeObserver in your dealloc method (again, see docs.)