Hi, I'm trying to build a nested array…
Don't do that. Parallel and nested arrays are harder to write and to read than real object-oriented solutions like the one eJames suggested, which is that of creating a model class.
Consider the code to set the item kind of every player's first item. With parallel/nested arrays:
for (NSArray *items in PlayerItems)
[[items objectAtIndex:0U] setKind:newKind];
With model objects:
for (Player *player in players)
[player setKind:newKind];
Which one is clearer?
The work required to maintain parallel and nested arrays, to keep them all synchronized for every change and to access any item in them, is far greater than the work required to create a model class. Additionally, if you decide to port to the Mac, not having a model class actively hurts you, as you can't use Bindings and implementing AppleScript support (not such a big deal for a game, I admit) is next to impossible.
As eJames also mentioned, you are leaking objects profusely. Follow his recommendation and read the Memory Management Programming Guide for Cocoa.
As pgb said, array indexes in Cocoa (and C, for that matter) start at 0. Moreover, you generally don't use indexes unless you have to; see my code examples above for a much clearer way to iterate on an array.
As pgb and Christian both point out, addObject:
is the method that returns void
, which you then cast to NSMutableArray *
. Perhaps you meant to put that cast inside the first pair of square-brackets? But this is another problem you wouldn't have if you had a real model class, as you would be setting up everything about the new Player at once, including his items:
Player *player = [[Player alloc] init];
//Set up name, SPECIAL stats, etc.
for (int kind = 1; kind < 50; ++kind) {
Item *item = [[Item alloc] init]; //I capitalized your class name for you.
[item setKind:kind];
[player addInventoryObject:item]; //Assume “inventory” is the name of the property that holds the player's items.
[item release];
}
[allPlayers addObject:player];
[player release];
This brings me to one more suggestion: You might also want to make a model class for the item kinds, and have an array of those somewhere. Then, each kind can have a name, an icon, perhaps a description, nature such as one-handed vs. two-handed, class requirements, stat requirements, etc., all right there in the item-kind object. The loop then looks like this:
for (ItemKind *kind in [self kindsOfItems]) {
Item *item = [[Item alloc] initWithKind:kind];
[player addInventoryObject:item];
[item release];
}
Additionally, if you design this kindsOfItems
property extensibly, you can allow players to add more item kinds later, either through plug-ins (Mac) or in-app purchasing (iPhone).