Category Archives: Arrays

Fast Enumeration, Massive Inefficiency

Cocoa makes use of a system called Fast Enumeration, which allows you to write array loops in a compact fashion and is also supposed to speed things up by getting [myArray nextObject] rather than getting [myArray objectAtIndex:nextIndex] on each pass through the loop. Here’s an example:

for (NSObject *anObject in myArrayOfObjects) {
    //do stuff
}

Because I’m an idiot, I had been using Fast Enumeration in situations where I needed to know the index of each object because I couldn’t be bothered to write out the code for incrementing an index. This resulted in incredibly readable stuff like the excrescence below:

for (NSObject *anObject in myArrayOfObjects) {
    if ([myArrayOfObjects indexOfObject:anObject] < ([myArrayOfObjects count] - 1) {
        NSObject *theNextObject = [myArrayOfObjects objectAtIndex:([myArrayOfObjects indexOfObject:anObject] + 1)];
        [self doSomethingWithObject:anObject andNextObject:theNextObject];
    }
}

In case your eyes are bleeding too much for you to be able to see how hard I’ve made things for myself, here’s a rundown of what the above code actually does:
Continue reading Fast Enumeration, Massive Inefficiency

Two dimensional C arrays – care and feeding

C arrays are a little hard to grasp by those of us raised on the Cocoa API, because most of the really convenient stuff (like an array object being able to keep track of its own size) just isn’t there in straight C.  I went into using C arrays, in order to interact with OpenGL, with absolutely no knowledge whatsoever (a common theme of this site!) of how to even use malloc.

Why would you want to use two-dimensional arrays anyway?  In my case, although I’ve written a fair few functions where e.g. a two-dimensional grid of points is mapped to a long one-dimensional array, and I’ve simply remembered what the dimensions of the grid were when accessing the information, sometimes this is simply too much for my poor brain to understand. In this situation I’m forced to represent things as a multidimensional array in order to get the concepts down in a way which works.  I might, therefore, have one array which represents all of the values of the x dimension, containing a series of arrays which represent the y dimension; so the point in the grid at (5, 13) is retrieved by getting the 13th value from the 5th subarray in the parent array.

Fortunately there are people who are much cleverer than me who have come up with a way of handling two-dimensional C-arrays.  Unfortunately I have forgotten the attribution.  However, I had to go forum-diving to find this and I think that it might be helpful for us inexperienced types to have a more easily-searched solution.  If I find the original source again, I will provide a link.

One similar implementation was found here

//make a 2d array of floats
 
float** Make2DFloatArray(long lengthMainArray, long lengthSubArray) {
    float **newArray = (float **) malloc(lengthMainArray * sizeof(float *));
    *newArray = malloc(lengthMainArray * lengthSubArray * sizeof(float));
    for (int i = 0; i &lt; lengthMainArray; i++) {
        newArray[i] = *newArray + i * lengthSubArray;
    }
    return newArray;
}
 
//release a 2d array of floats
 
void free2DFloatArray (float **arrayToFree) {
    free(*arrayToFree);
    free(arrayToFree);
}
 
//access a value in the 2d array
 
float theFloatIWant = my2DFloatArray[indexInMainArray][indexInSubArray];

Sorting objects into an array of NSArrays

This one is pretty simple, but I had a terrible amount of difficulty working out how to do this the first time.  Cocoa makes a lot of this process pretty easy by providing the NSMutableArray class – the only real gotcha with an NSMutableArray is the “object was mutated while being enumerated” problem.  This means exactly what it says – you’ve removed an object in the array while enumerating (going through the objects one by one) the same array.  The usual workaround is to create intermediate arrays with lists of objects to delete and then enumerate over the intermediate and commit changes to your NSMutableArray.

NSArrays can only contain objects; if you want to store ints, floats etc. then you are going to need to encapsulate them in an NSObject of some sort (e.g. in this case, an NSNumber would be a suitable fit).  All of the objects in an NSArray need to be of the same class.

Say I want to make a very simple hierarchical data store which will provide the data for part of the user interface for an app; for example, a UITableView.  I want my tableView to have sections which are organised by date – you can see this sort of arrangement in, for example, email programs which sort your incoming mail by Today, Yesterday, Last Week, etc.  One simple way to do this is to establish a hierarchical structure of arrays, like so:

Master array       –> section array –> content object

–> section array (empty)

–> section array –> content object

–> content object
–> content object

Continue reading Sorting objects into an array of NSArrays