I'm looking at an Objective-C sample project at:
https://developer.apple.com/library/mac/samplecode/FunkyOverlayWindow/Introduction/Intro.html
I don't understand how main.m passes control to the other classes/objects.
Let me explain what I'm trying to do. I'm trying to build that app, step by step. My first step was to get main.m to compile. I believe this is the starting point for most applications. I don't know what to add/compile next, because main.m does't mention/refer to any of the classes in that project.
Any ideas?
The entry point in Objective-C programs is the function called main(). See the following code from main.m
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argue);
}
The main() function begins by calling a function named NSApplicationMain() that is cocoa framework function and not shown to user, which is functionally similar to the following:
void NSApplicationMain(int argc, char *argv[])
{
[NSApplication sharedApplication];
[NSBundle loadNibNamed:#"myMain" owner:NSApp];
[NSApp run];
}
Thus, [NSBundle loadNibNamed:#"myMain" owner:NSApp] is called by NSApplicationMain function and in this time, #"myMain" is identifier for Main Interface(as MainMenu.xib within sample source)
finally MainMenu.xib is run, and then OverlayWindow that is main window of MainMenu.xib will be run.
I appreciate, and understand perfectly, how you could not want to use Xcode - especially if, like me, you come from a Unix/GCC/Makefile environment. However, there are some things that are really quite hard to do without the Xcode GUI and linking buttons and widgets to your code is one of those things.
In Xcode, you click the button in your user interface and drag a line to the code attached to it - these are called IBOutlets and IBActions. So, my first suggestion is to Google those two terms.
Secondly, I recommend you watch this video on YouTube to understand what the XIB/NIB is and how to link it to your code and then you can try and do it without Xcode once you get the concept... video showing linking buttons to code.
Related
How to view XCode( assembly code equivalent) at the break point?
I have gone to Thread1 and it shows objective-c for the [ViewController viewDidLoad] and then assembly for [UIViewController view] and [UIWindow makeKeyAndVisible]. I want to be able to see the assembly for [ViewController viewDidLoad] with the marker at the break pt?
(Product->GenerateOutput->Generate Assembly File: doesn't show the break pts.)
thx
void addme(int *a)
{
*a += 0xFF;// <-- I want to see the assembly for this: should see an instruction "ADD" in the assembly break down
*a += 1;
*a += 2;
}
- (void)viewDidLoad
{
[super viewDidLoad];
int a = 12;
addme(&a);
}
Steps:
Put breakpoint where you want to see the assembly code
Run program
Once program pauses hit the button that looks like ->| (but pointing down)
Repeat step 3 a lot
Dance
See the world
Wonder at the joys of life
Pop bottles
Grow old
Die
I'm not quite sure this is what you're asking for, but I just did it (well, steps 1-5 & 8) and it worked for me.
It's at the bottom of the screen, above the console.
And it's also likely that you won't see an assembly ADD instruction at all, since compile time constants are calculated and thus optimized away by the compiler at compile time.
#jdl At the matter of fact i don't know Objective-C and #Dustin doesn't know asm... As i understood viewDidLoad function will execute a code in it when some object is loaded. In my opinion you can compile only that part of code which you included in your question and look into assembly code via IDA pro for Mac OS or some other debugger.
I just started doing iPhone dev. At the moment I'm trying to fix a bug which exists in an already built app. The main function looks as follows:
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
This seems pretty typical from what I understand; I'm guessing UIApplicationMain is the main loop, which the source files that have been created for the app specifically connects to via the use of delegates/function pointers in Objective-C (note, while I'm quite proficient in C++, I hardly know much about iOS or Objective-C).
So, what I'd like to know is how I can step through my source files and track down the calculation bug I'm experiencing for this app. Unfortunately, all I receive is disassembly when stepping into the UIApplicationMain, and while I know the very basics of asm and can interpret it (for the most part), I'd rather not unless I absolutely have to - especially considering the fact that the debugger appears to be outputting AT&T syntax (NOTE: if it's possible to change the asm syntax to Intel, I'd appreciate it if someone could state how to do that).
Thanks.
You can put breakpoints on every line by clicking on the gray space between the code and the project explorer on the left. When running, upon encountering a breakpoint the simulator or device will stop running and the code will show up. Then hit either the down arrow button that will show up on the upper left of the debugging window at the bottom to go line by line, which will show asm when appropriate, or hit the right-pointing arrow which will run until the next breakpoint is hit. You can disable breakpoints by deleting them individually or by toggling the breakpoints button at the top.
The main function in iOS is almost identical in all projects. It just serves to get the ball rolling. Here is a good tutorial for debugging especially crashes in Xcode. debugging tutorial
(Answer to NOTE not the actual question)
xcode can be set to use gdb (in scheme settings):
simply add to your .gdbinit
(which is located in your home dir ) :
"set disassembly-flavor intel"
for lldb there might be something similar
I want to run my app on the iPad...I upgraded to Xcode 4.3 and iOS 5.1 and the app doesn't work anymore. The strange thing is that the app don't reach the entry point, the main method is not called. Have you got any ideas what the reason could be?
int main(int argc, char *argv[])
{
NSLog(#"test main"); //not visible in debugger
}
I know it is not much information but I don't know what info I should give
You need to move your NSLog call into your AppDelegate. Put it into the applicationDidFinishLaunching method. The reason you can't NSLog in main is that the core foundation libraries have not yet been loaded there.
I've been asked to reduce the startup time of an iOS application. I am very familiar with the platform/tools in general but I haven't focussed upon application startup time before. I'm wondering if there are known patterns for attacking this problem?
I realize that I can simply measure the time it takes to go from main() through the completion of application:didFinishLaunchingWithOptions: (which includes any background loading tasks), but again, I am hoping there might be a more standardized way to do this.
Any suggestions would be greatly appreciated!
-M
from WWDC 2012 session 235
set the start point at the first line of code in main.m
#import <UIKit/UIKit.h>
CFAbsoluteTime StartTime;
int main(int argc, char *argv[])
{
StartTime = CFAbsoluteTimeGetCurrent();
#autoreleasepool {
...
set the end point somewhere in AppDelegate's application:didFinishLaunchingWithOptions:
extern CFAbsoluteTime StartTime;
...
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Launched in %f sec", CFAbsoluteTimeGetCurrent() - StartTime);
});
Your method sounds like the correct one (I recommend using CFAbsoluteTime for your measurements).
One thing which may help you reduce the launch time is to avoid having View Controllers loaded from nibs on application launch. If I am not mistaken this forces them to be loaded into memory even before your app launches. Instead, alloc and init your view controllers dynamically when you need them. Note that you can still have the Views you'd like to be loaded by the view controllers stored in Nibs, you don't have to stop using IB. Just don't use IB to set static outlets for your app delegate.
In an Xxode project that has a lot of .h and .m files, how do you determine which file gets executed first?
The file that contains int main(int argc, char * argv[]); will get run first, since the main() function is the first function to get run. In pretty much every Xcode template project, that file is called "main.m".
edit
Usually, the main() function of a Cocoa Touch app is this:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
(Substitute NSApplicationMain() for UIApplicationMain() and remove the autorelease pool if you're writing a Mac app)
edit #2
I'm only interested in the file that gets run first from the classes folder
The simple answer is "The application delegate", then everything else.
The technical answer to that is that any objects in your MainMenu.xib (Mac) or MainWindow.xib (iOS) file will be instantiated first. Usually the objects in that file will be instantiated in the order in which they appear, but I don't think that's guaranteed.
So if you 3 have custom top-level objects in your MainWindow.xib file, then they'll all be instantiated at the same time (within reason). First their initWithCoder: methods will execute, then some time later their awakeFromNib methods will execute (which usually the safest "starting point" for that object).
The application delegate launch methods will happen somewhere along in there too (I believe in between initWithCoder: and awakeFromNib).
Cocoa and Cocoa-Touch apps are completely event-driven. It is not that the order the methods are executed can be understood by reading the source code files.
As Dave explained, the entry of the program is at the main function in main.m. It immediately calls UI/NSApplicationMain.
NS/UIApplicationMain is a function provided by Cocoa(-Touch). It watches the user interaction, and fires events accordingly.
For example, when the user clicks a button, the system calls automatically what you provided as the action method specified in the xib file.
Another example is the drawRect: method you provide: it's called when the system decides to draw an object onto the screen. It's very important that you don't actively draw to the screen. The system asks you to draw the screen, and you respond.
One important set of events are the ones which are called at the beginning of the program, like applicationDidFinishLaunching: or the ones which are called when a view is loaded from the xib file, viewDidLoad.
Aaron Hillegass made a great analogy of the situation: you're KITT and respond to Michael Knight's order, not the other way around. Well you need to be over certain age to understand this analogy...
Another thing that should get run first is in an App Delegate (Defined like so: NSObject <UIApplicationDelegate> and setup in the nib) the method applicationDidFinishLaunching
This is obviously not technically the first thing to be run. The main loop and whatever is in UIApplication will be executed first, but in general this is good starting point for iOS applications and the first place you really have control.
You can also create a class called like "Controller" and drag an NSObject into your nib and set the class to Controller. Then the method awakeFromNib will be called.
Either of these should be fine to set up your app.