Reputation: 6773
I would like to use an array of pointers to instances of objects, but only want to create instances of those objects when required (i.e. lazily). The array corresponds to a table in the UI, so each array index corresponds to a table row.
I would like to use an NSMutableArray to hold pointers to the object instances as they are created (which occurs when the user selects the corresponding row in the UI).
If a row in the table is selected, the corresponding array entry is checked. If the pointer value is nil, the instance hasn't yet been created, and so it is created at that point, and the object pointer is stored in the corresponding indexed array entry.
Obviously, this requires that I initially start with an array of nil pointers, but objC won't let me put a nil pointer in an NSArray.
I can't just add objects to the array as they are created, as the array index would not correspond to the table row.
What's the best objC solution here?
Upvotes: 3
Views: 1648
Reputation: 727047
The idiomatic solution in Objective C is to use NSNull
:
The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
Create your NSMutableArray
, and fill it up with [NSNull null]
objects:
NSMutableArray *array = [NSMutableArray arrayWithCapacity:N];
for (int i = 0 ; i != 10 ; [a addObject:[NSNull null]], i++);
When you check for the presence or absence of an object in your NSMutableArray
, compare the object at index to [NSNull null]
: if they are the same, replace with a real object; otherwise, the real object is already there.
if ([array objectAtIndex:index] == [NSNull null]) {
MyRealObject realObject = [[MyRealObject alloc] init];
[array replaceObjectAtIndex:index withObject:realObject];
}
** edit summary ** edited to initialize the array using a loop (thanks bbum).
Upvotes: 7
Reputation: 162722
NSMutableArray doesn't support sparse arrays. Thus, you could pre-seed the array with NSNull instances (or some other "no object" marker). Something like:
a = [NSMutableArray array];
for(int i = 0; i<numberNeeded; i++) [a addObject:[NSNull null]];
Or, if your array is going to be truly sparse, consider the use of some kind of map instead. NSMutableDictionary will work, but requires objects for keys and all that boxing/un-boxing is painful in some cases. Alternatively, a CFDictionary can easily be configured to use integer keys with object values.
While a dictionary is obviously slower for lookup-by-index, that performance difference is unlikely to cause a problem in most cases (but not all).
Upvotes: 3