I'm trying to build a nested array: First, I make a "PlayerItems" array which will contain 10 arrays, each containing item objects, corresponding to the inventories of each player in the game. On the indicated line, I get the following error:
error: void valued not ignored as it ought to be
What is the void value here? If I used [[PlayerItems objectAtIndex:i] addObject:myitem]
instead, the program compiles but crashes. If I comment that line out, it compiles and runs OK. Thank you for your help!
self.PlayerItems = [[NSMutableArray alloc] initWithCapacity:11];
NSMutableArray *itemarray = [[NSMutableArray alloc] initWithCapacity:60];
item *myitem = [[item alloc] init];
item.kind = 1;
for (int i = 1; i < 10; i++) {
itemarray = [[NSMutableArray alloc] initWithCapacity:60];
[PlayerItems addObject:itemarray];
for (int i2 = 1; i2 < 50; i2++) {
myitem = [[item alloc] init];
myitem.kind = 1;
// The error occurs on the line below:
((NSMutableArray *) [[PlayerItems objectAtIndex:i] addObject:myitem]);
}
}
The arrays in Objective-C are zero based, and your for loop is starting in 1. You should change it to
As for the void error, you don't need to cast the return value of
addObject:
since it returns void, that's why you are getting the warning.That line should read:
I would do it as follows:
As a side note, you should definitely read up on memory management in Cocoa, since your original code is full of memory leaks. It can be a bit difficult to wrap your head around at first, but once you learn it, it becomes second nature. Well worth the effort.
update:
A more object-oriented way to do this would be to create a
Player
class, and have eachPlayer
manage its own set of items:Player.h
Player.m
Elsewhere
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:
With model objects:
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 returnsvoid
, which you then cast toNSMutableArray *
. 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: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:
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).In the last line you're calling addObject: which returns void:
You then try to cast void to NSMutableArray*. And you also don't assign the casted void to anything.
To add the subarray to your array this should be sufficient:
BTW: You're creating only 9 arrays and you're adding only 49 subarrays.