views:

276

answers:

5

I'm curious, what role does the int main function play in a Cocoa program? Virtually all of the sample code I've been looking at has only the following code in main.m:

#import <Cocoa/Cocoa.h>


int main(int argc, char *argv[])
{

    return NSApplicationMain(argc,  (const char **) argv);
}

What exactly is this doing, and where does the program actually start stepping through commands? It seems my conceptions need readjustment.

+4  A: 

main() is the entry point for your program.

When you run your program that is the first function called. Your program ends when you exit that function.

Also note that this does not come from Objective-C. This is simple C.

Have a look at Wikipedia's page on it

pfandrade
Thanks for answering. Unfortunately, I think I must have worded my question poorly. I'm aware of what int main() is, what I'm confused about is the fact that the above code is the only code in int main() in every sample project I've looked at. I'm wondering where the code begins executing (like why does an NSView subclass execute and draw without me explicitly calling it?) and if I'm not supposed to stick my main loop in int main() where does it go?
Arthur Skirvin
It might also be helpful to note which things are NOT inside the entry point, such as: library imports, class definitions, function prototypes, function definitions, global variables, and some other goodies. Basically, as pfandrade pointed out, the entry point is where you program starts and ends.
pokstad
@Arthur, there is still an int main when events are handled. There is a loop inside the 'int main' that is constantly listening for events. For example, when the screen is redrawn, it is due to a change in the screen that the event loop is looking for. Check out this wiki article: http://en.wikipedia.org/wiki/Event_loop
pokstad
It's just weird to me coming off a little experience in C++. It looks unnatural that the main function would be so empty.
Arthur Skirvin
@Arthur See my answer below, I tackled your concern about the NSView.
pokstad
+5  A: 

Since a Cocoa project starts like any other, the entry point for the Operating system is main. However the Cocoa Architecture is constructed to actually start the processing of your program from NSApplicationMain, which is responsible for loading the initial window from your application and starting up the Events loop used to process GUI events.

Apple has a very in depth discussion on this under the Cocoa Fundamentals Guide : The Core Application Architecture on Mac OS X

Brandon Bodnár
Ok, cool. That link is pretty much exactly what I was looking for. One quick question if you have the time: how can I get events added to the event queue that don't originate from user input, but from the startup of the application? And of course, thanks a lot. That is a very very helpful guide.
Arthur Skirvin
No problem. Actually you will probably want to use the events that are already used at the startup of the application. For Mac Programming, the Main Nib (Xib) file should have a delegate that conforms to NSApplicationDelegate. This delegate will have two selectors called on startup applicationWillFinishLaunching: and applicationDidFinishLaunching:. use those to preform code that should happen at App startup. In the templates for XCode, the project normally creates an AppDelegate class that will have a stub of applicationDidFinishLaunching for you.
Brandon Bodnár
You're coming through for me all over the place. That, again, is exactly what I wanted to know. Thank you kindly!
Arthur Skirvin
+3  A: 

If you want to learn how control passes from "launch this" to the main() function, the execve man page has the details. You would also want to read about dyld. main() is a part of the Unix standard. Every single program that you can run effectively has a main().

As others have mentioned, NSApplicationMain passes control to Cocoa. The documentation is quite specific as to what it does.

One interesting note, NSApplicationMain doesn't actually every return. That is, if you were to separate the call to NSApplicationMain from the return in your main function and put code in between, that code would never be executed.

bbum
Hey there and thanks for answering. That documentation link helps clear up some of my questions. By the way, the execve and dyld links don't seem to be working. Again, thanks!
Arthur Skirvin
Arthur Skirvin: They work fine once you fix Stack Overflow's mangling (it hates the x-man-page: scheme). I've replaced them with links to the online versions.
Peter Hosey
Oooh... bummer. I'll stop doing that.
bbum
A: 

Value returned from main is returned by the process to operating system when the process is done.

Shell stores the value returned by last process and you can get it back with $? :

> ls
a b c

> echo $?
0

> ls x
x: No such file or directory

> echo $?
1

ls is an application like anything else.

You can use the return value to chain multiple processes together using shell script or anything else that can execute a process and check for return value.

stefanB
A: 

I'm wondering where the code begins executing (like why does an NSView subclass execute and draw without me explicitly calling it?) and if I'm not supposed to stick my main loop in int main() where does it go?

In an xcode project you have a main.m file that contains the 'int main' function. You won't actually find the code that calls the NSView draw explicitly, this code is hidden deep within an iPhone or Mac OS X framework. Just know that there is an event loop hidden deep within your 'int main' that checks for changes so that it knows when to update your view. You don't need to know where this event loop is, it's not useful information since you can override methods or create and assign delegates that can do things when this happens.

To get a better answer, you'll need to explain what you mean by a 'main loop' that you wanted to put inside the 'int main' function.

It's just weird to me coming off a little experience in C++. It looks unnatural that the main function would be so empty.

You can encapsulate a billion lines of code into one function and put it into 'int main'. Don't be deceived by a main only having a few lines, that is done on purpose. Good programming teaches us to keep code in specific containers so that it is well organized. Apple chose to make the "real" launch point of their iPhone apps in this single line of code inside the main.m file:

int retVal = UIApplicationMain(argc, argv, nil, @"SillyAppDelegate");

From that one piece of code, an app's delegate is launched and won't return control to the main function until it is done.

pokstad
Alrighty, that bit about about NSView gives me some clarity. I know that an ungodly amount of code can be represented by a single line in int main or anywhere else; the unnaturalness of Cocoa's main function came from the fact that it just immediately returns. Seeing as I've always indicated the end of my apps by 'return 0' in C++ it appeared to me at a glance that this Cocoa setup would just quit immediately after launch. I didn't understand this whole hidden event loop business.The 'main loop' I was referring to is this hidden loop. I'm just used to constructing it myself. Thanks!
Arthur Skirvin