Quick Question (enumeration to update an array)

Discussion in 'Mac Programming' started by badjujuman, Sep 17, 2008.

  1. macrumors newbie

    Joined:
    Jul 12, 2008
    #1
    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.

    Code:
    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.
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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)
    Code:
    
    // 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.
     
  3. thread starter macrumors newbie

    Joined:
    Jul 12, 2008
    #3
    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.
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    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?
     
  5. thread starter macrumors newbie

    Joined:
    Jul 12, 2008
    #5
    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.
     
  6. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    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

    Code:
    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:

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

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    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
     
  8. thread starter macrumors newbie

    Joined:
    Jul 12, 2008
    #8
    Hey thanks for the help on this guys. I really appreciate it. I'm gonna use this and update my podcast accordingly.
     

Share This Page