PDA

View Full Version : Quick Question (enumeration to update an array)




badjujuman
Sep 17, 2008, 10:17 AM
Hi, I am working on my learning podcast for objective-c, and I'm not quite sure if this code will work. I'm trying to use fast enumeration to update an array of counters as an example.

NSArray *array = [NSArray arrayWithObjects:
[NSNumber numberwithInt: 2],
[NSNumber numberwithInt: 1],
[NSNumber numberwithInt: 0],
nil;]





for (NSNumber *numberwithInt in array) {

if (numberwithInt > 0)
{
numberwithInt++
}

}


This is the code that I came up with after researching it a bit, but I'm not sure if it's right or not. Can someone help me? It's the only thing holding me back from uploading my latest episode.



robbieduncan
Sep 17, 2008, 10:25 AM
for (NSNumber *numberwithInt in array) {

if (numberwithInt > 0)
{
numberwithInt++
}

}


This loop won't work. At all. Nothing will be changed by this. numberwithInt is a pointer. So numberwithInt++ increments the pointer. This is basic C. So what you have done is changed the address in memory that numberwithInt is pointing at. Fortunately you didn't try and access that memory otherwise your program would probably crash.

Next: NSNumber is immutable. So even if you had tried to use the pointer correctly you can't increment an NSNumber. All you can do is create a new NSNumber with the incremented value.

This should be correct (not tested)


// We can't use fast enumeration as we need to change the
// object that the array index is pointing at. So we need loop
// variables
int i, count = [array count];
NSNumber *num;
for (i=0;i<count;i++)
{
num = (NSNumber *) [array objectAtIndex:i];
if ([num intValue]> 0)
{
[array replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:[num intValue]+1]];
}
}

Note that this assumes array is a NSMutableArray: you can't alter the values in an NSArray once it's been created.

Edit to add: is there a particular reason you're not using a C array? A C array of ints would behave how you seem to expect.

badjujuman
Sep 17, 2008, 10:43 AM
Oh, from what I researched on fast enumeration I thought that updating an array of counters might be a simple possibility I could pose to my audience. See I am doing this as a job for my professor and I am still learning objective-c myself, so I didn't know exactly what fast enumeration does. If someone has a good example that I might be able to use for my podcast I would be greatly appreciated.

robbieduncan
Sep 17, 2008, 10:49 AM
Fast enumeration does exactly what it says it does. It enumerates the contents of the container class setting the specified pointer variable to point at an object from the container each time through the loop ensuring that each item in the container is pointed to exactly once.

As you are doing this for a real audience and are be paid (I assume) I'd suggest you try and actually understand what you are doing. Do you even know how pointers work? Do you understand pointer arithmetic and why incrementing a pointer does not, in any way, effect the object or value being pointed at?

badjujuman
Sep 17, 2008, 11:18 AM
No I'm doing this for my University, although my professor expects thousands of people to watch, but that's a different story. Yes I know what pointers are and what they do, I was learning to program in C#, but then they drop objective-c in our laps and want us to learn that too. I know that incrementing the pointer does not affect the object at all, but I didn't realize that fast enumeration only affected the pointers in a collection. From what I read on it, I thought it was working with what was inside a collection not the pointers. I apologize, I'm still learning too. Thank you for clarifying this for me though, now I will change this for my podcast.

robbieduncan
Sep 17, 2008, 11:42 AM
I know that incrementing the pointer does not affect the object at all, but I didn't realize that fast enumeration only affected the pointers in a collection.

Please don't take this as an attack: it isn't. I simply want to make sure that people learning Objective-C/Cocoa are actually thinking about what they are doing.

If we look at a fast enumeration declaration we see something like


for (Classname *variableName in pointerToCollection)
{
}

That *variableName is clearly a pointer to an object. And as Classname can be any class name it's clear that you have to call methods that the class responds to on that instance. At no point does it look like you should be able to call ++ or -- on this and expect the object to alter or respond.

I'd suggest a better example of fast enumeration would be something like this:


- (NSString *) stringArrayConcat:(NSArray *) array
{
NSMutableString *ms = [NSMutableString string]
for (NSString *component in array)
{
[string appendString:component];
}
return ms;
}

lee1210
Sep 17, 2008, 04:05 PM
Just to point this out, in case it led to some of the confusion:
Objective-C does not support operator overloading.

Without knowing this, one might assume that a class representing a number could have a unary increment operator applied to it.

This may not have been the case, but I thought I'd mention it.

-Lee

badjujuman
Sep 22, 2008, 08:51 AM
Hey thanks for the help on this guys. I really appreciate it. I'm gonna use this and update my podcast accordingly.