Search code examples
iosobjective-cxcodecocos2d-iphonespritebuilder

Debugging trivial functions in Objective-C


Recently I just started working on iOS game programming, and I find several things confusing. (FYI, I am working on a simple game with code provided on makegamewith.us)

First, I just found out that only the main function is executed. By this I mean we use the main function to activate iOS simulator, so that we will be able to load our game. Then I realize that breakpoints only work in main functions. As I put breakpoints in other files (such as creature.m, a game component), despite that I use a function to create creature objects in the game, Xcode won't stop at that function. The iOS simulator will be called, and then the game will be automatically loaded.

So here is the question: how can I debug then?

I assume that function is called when I run the game, but Xcode just ignores any other function in other files except the main function in main.m.

Also, I encountered several "Couldn't find member variable" situations. I wonder how to prevent this from happening. The whole sprite builder publishing to Xcode thing appears blurry. I would appreciate if someone can explain how the whole thing works.

Update:

I realize that I didn't explicitly call any of the functions I have in other files (for instance, Grid.m as shown below). By main function, I mean the int main function in main.m. So the problem might possibly be that I didn't explicitly call that function in main? (but I think what main.m is responsible for is launching the program.)

In main.m:

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

@autoreleasepool //if I put a breakpoint here this will definitely work
{
    int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
    return retVal;
    }
}

Grid.m

#import "Grid.h"
#import "Creature.h"

// these are variables that cannot be changed
static const int GRID_ROWS = 8;
static const int GRID_COLUMNS = 10;

@implementation Grid {
    NSMutableArray *_gridArray;
    float _cellWidth;
    float _cellHeight;
}

- (void)onEnter
{
    [super onEnter];

    [self setupGrid];

    // accept touches on the grid
    self.userInteractionEnabled = YES;
}

- (void)setupGrid //****if I put breakpoint here, it doesn't work****
{
    // divide the grid's size by the number of columns/rows to figure out the right width and height of each cell
    _cellWidth = self.contentSize.width / GRID_COLUMNS;
    _cellHeight = self.contentSize.height / GRID_ROWS;

    float x = 0;
    float y = 0;

    // initialize the array as a blank NSMutableArray
    _gridArray = [NSMutableArray array];

    // initialize Creatures
    for (int i = 0; i < GRID_ROWS; i++) {
        // this is how you create two dimensional arrays in Objective-C. You put arrays into arrays.
    _gridArray[i] = [NSMutableArray array];
    x = 0;

    for (int j = 0; j < GRID_COLUMNS; j++) {
        Creature *creature = [[Creature alloc] initCreature];
            creature.anchorPoint = ccp(0, 0);
            creature.position = ccp(x, y);
            [self addChild:creature];

            // this is shorthand to access an array inside an array
            _gridArray[i][j] = creature;

            // make creatures visible to test this method, remove this once we know we have filled the grid properly
            creature.isAlive = YES;

            x+=_cellWidth;
        }

        y += _cellHeight;
    }
}

@end

Solution

  • Take a look at your main() function -- almost the only thing it does is to call UIApplicationMain(). This is true for any iOS application. So the real work is being done by UIApplicationMain(), and we should find out about that. Here's the description from the docs:

    This function instantiates the application object from the principal class and instantiates the delegate (if any) from the given class and sets the delegate for the application. It also sets up the main event loop, including the application’s run loop, and begins processing events. If the application’s Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.

    So if there's a problem with your app, it's likely related to the application delegate, your AppController class. Set a breakpoint in your -[AppController application:willFinishLaunchingWithOptions:] method -- that's what the application itself will call on its delegate when the app is ready to run. Your UIApplicationMain() call in main() looks OK, so the debugger should hit a breakpoint in your ...didFinishLaunching... method. Step through that method and make sure that you're setting up a window, setting a root view controller, etc. If you're not sure what needs to happen, try creating a new single-view project and looking at the code that's provided there.