+initalize
is sent to a class the first time it or one of its subclasses receives a message for the first time. So, when you do:
instance = [[[YourClass alloc] init] autorelease];
That alloc
message triggers initialize
.
If you do the same thing with a subclass:
instance = [[[SubclassOfYourClass alloc] init] autorelease];
That alloc
message will trigger +[YourClass initialize]
the same way the other one did (prior to also triggering +[SubclassOfYourClass initialize]
. But only one of these will do it—each class's initialize
never gets called more than once. (Unless you call it yourself with [super initialize]
or [SomeClass initialize]
—so don't do that, because the method won't be expecting it.)
-init
, on the other hand, initializes a new instance. In the expression [[YourClass alloc] init]
, you are personally sending the message directly to the instance. You may also call it indirectly, through another initializer ([[YourClass alloc] initWithSomethingElse:bar]
) or a convenience factory ([YourClass instance]
).
Unlike initialize
, you should always send init
(or another initializer, if appropriate) to your superclass. Most init methods look roughly like this:
- (id) init {
if ((self = [super init])) {
framistan = [[Framistan alloc] init];
}
return self;
}
Details differ (this method or the superclass's or both may take arguments, and some people prefer self = [super init]
on its own line, and Wil Shipley doesn't assign to self
at all), but the basic idea is the same: call [super init[WithSomething:…]]
, make sure it didn't return nil
, set up the instance if it didn't, and return whatever the superclass returned.
This implies that you can return nil
from init
, and indeed you can. If you do this, you should [self release]
, so that you don't leak the failed object. (There are few reasons to do this, however. For detecting invalid argument values, you should use NSParameterAssert
instead.)
How can I use this to create an instance of my AppController with instance variables that make up my interface?
The best way is to do it all in main
:
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppController *controller = [[[AppController alloc] init] autorelease];
[[NSApplication sharedApplication] setDelegate:controller]; //Assuming you want it as your app delegate, which is likely
int status = NSApplicationMain(argc, argv);
[pool drain];
return status;
}
You'll do any other set-up in your application delegate methods in AppController
.
You already know this, but for anyone else who reads this: Nibs are your friend. Interface Builder is your friend. Don't fight the framework—work with it, and build your interface graphically, and your application will be better for it.