2

How do you fill a NSMutableArray with a set capacity for later use?

Basically I want to set up a NSMutableArray to act as a map for my game objects, so I have this line...

gameObjects = [[NSMutableArray alloc] initWithCapacity:mapWidth*mapHeight];

Which I had hoped would create and fill my MutableArray so I can get then access it with this kind of index...

int ii = (cellY*mapWidth)+cellX;

NSDictionary *currentObject = [gameObjects objectAtIndex:ii];

But I just learned initWithCapacity doesn't fill the array, so should I create blank objects to fill it with, or is there a Null that I can fill it with? Also would I do that with 2 for loops or is there an instruction something like "initWith:myObject" ?

I want to be able to check at a certain index within the array to see if there's an object there or not, so I need to be able to acces that index point, and I can only do that if there's something there or I get an out of bounds error.

I'll be using this NSMutableArray pretty much as a grid of objects, it's a 1 dimensional array organised as a 2 dimensional array, so I need to be able to fill it with mapWidth*mapHeight of something, and then calculate the index and do a check on that index within the array.

I've looked on here and googled but couldn't find anything like what I'm asking.

Thanks for any advice.

Phil
  • 2,995
  • 6
  • 40
  • 67
  • While you can use NSNull or you custom class instances as a placeholders, I'd recommend to consider refactoring so that you are not trying to access the object which is not set, I mean your indexes probably need to be better organized. – A-Live Nov 05 '12 at 01:23
  • So I can do a check to see if an object is at that exact x,y position in the array. – Phil Nov 05 '12 at 02:03

3 Answers3

4

I think what you are looking for is [NSNull null]. It is exactly what you want- a placeholder value.

You can find more information on the topic in this question.

Community
  • 1
  • 1
eric.mitchell
  • 8,817
  • 12
  • 54
  • 92
3

initWithCapacity is just a performance optimization -- it has no effect on the array behavior, it just keeps the code "under the covers" from having to repeatedly enlarge the internal array as you add more entries.

So if you want a "pre-allocated" array, you'd need to fill it with NSNull objects or some such. You can then use isKindOfClass to tell if the object is the right type, or simply == compare the entry to [NSNull null]. (Since there's only ever one NSNull object it always has the same address).

(Or you could use a C-style array of pointers with nil values for empty slots.)

But you might be better off using an NSMutableDictionary instead -- no need to pre-fill, and if the element isn't there you get a nil pointer back. For keys use a NSNumber object that corresponds to what would have been your array index.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • 1
    I've gone with the [NSNull null] approach and that seems to work, but your NSDictionary idea is intriguing, you say no need to pre-fill, but how would I set that up to give me the correct keys in a for loop? – Phil Nov 05 '12 at 01:54
  • @Phil -- Well, I don't know precisely what you'd need the for loop for, but you can use, eg, `allKeys` to give you a list of the key values (in arbitrary order). However, if you, in addition to your random access, need to be able to access the "array" in serial order then the NSMutableDictionary may not be the best choice (at least not without some other auxiliary structure). – Hot Licks Nov 05 '12 at 02:03
0

initWithCapacity only hints to NSMutableArray that it should support this many objects. It won't actually have any objects in it until you add them. Besides, every entry in the array is a pointer to an object, not a struct like you'd normally have in a standard c array.

You need to change how you're thinking about the problem. If you don't add an object to the array, it's not in there. So either you pre-fill the array with "empty" objects as you've said, which is weird. Or you can add the objects as you need them.

yfrancis
  • 2,616
  • 1
  • 17
  • 26
  • Hmm the thing is I want to be able to check at a certain index within the array to see if there's an object there or not, so I need to be able to acces that index point, and I can only do that if there's something there or I get an out of bounds error. – Phil Nov 05 '12 at 01:24
  • if you check the count before trying to access the index, and its less than the index, then there's no object there – yfrancis Nov 05 '12 at 01:30
  • I'll be using this NSMutableArray pretty much as a grid of objects, it's a 1 dimensional array organised as a 2 dimensional array, so I need to be able to fill it with mapWidth*mapHeight of something, and then calculate the index and do a check on that index within the array, someone above suggested NSNull so I could try that I guess. – Phil Nov 05 '12 at 01:34
  • interesting, never thought of using NSMutableArray to represent a 2d matrix (i would have just gone with a standard c array). You have to keep in mind that lookup in NSArray is not always near constant time, its logarithmic in some cases, so be careful if you're using large dimensions. – yfrancis Nov 05 '12 at 02:02