Cocoa has "init" methods, which are usually called right after allocation to initialize objects, for instance:
myString = [[NSString alloc] initWithCharacters:chars length:len];
Typically you nest the alloc and initXXX calls, as init might change the object returned by alloc.
Each class can have as many initXXX methods as it wants, but typically a very small number is known as "designated" initializers, which is what all the other init methods end up calling. The designated initializers then in turn are the ones call init methods in the superclass, allowing all superclasses to initialize parts of the object they care about. (Eventually it all boils down to NSObject's init method.)
Subclassers which want to have init methods should normally override the designated initializers, so that other init methods automatically do the right thing (by going through the subclass method).
All this is not a language requirement, but it's a good policy, and one that most Cocoa classes follow.
As far as where to initialize instance vars. awakeFromNib is reasonable for objects created from nib, but it won't get called for objects created programmatically. If you want to allow programmatic creation of your object, you would usually make sure your init methods (preferably just the designated initializers) go through the same code path awakeFromNib does to initialize them.
One more note: Objects coming from nib and other object archives first get alloc, then initWithCoder:, then awakeFromNib. initWithCoder: is usually where ivars are read from the archive and initialized. awakeFromNib is best for doing somewhat deferred initializations, ones which make sure that all of the outlets and such are also initialized. (At initWithCoder: time, other objects being loaded from the nib might not yet be initialized themselves...)
I hope I didn't confuse you too much,
Ali
[This message has been edited by ali (edited 02-11-2001).]