Need help with CGRect in NSArray

Discussion in 'Mac Programming' started by teek, Mar 24, 2010.

  1. teek macrumors member


    Feb 12, 2008
    // create CGRect
    CGRect rect = CGRectMake(0, 20, 7.5f, 7.5f);
    // create Array
    NSMutableArray *foo = [[NSMutableArray alloc] init];
    // add the rect
    [foo addObject:[NSValue valueWithRect:rect]];

    // get the rect
    CGRect theRect = [[foo objectAtIndex:0] CGRectValue];
    // increase y offset
    theRect.origin.y += 20;

    CGRect theRectAgain = [foo objectAtIndex:0];

    theRectAgain.origin.y is still 20!

    Clearly I lack some knowledge here, what is going on, why is theRectAgain.origin.y still 20?
  2. gnasher729 macrumors P6


    Nov 25, 2005
    First, the code reading theRectAgain definitely doesn't work. Second, when you changed theRect, you changed a copy of the value. The original in the NSArray is not modified at all. You might consider good old malloc/realloc/free or std::vector, depending on what you are planning to do.
  3. teek thread starter macrumors member


    Feb 12, 2008
    Sorry my bad that should be:

    CGRect theRectAgain = [[foo objectAtIndex:0] CGRectValue];

    I'm just adding CGRect's to an array whenever I click somewhere in my view.

    then later I want to change the rect's origin x and y for all the rect's in the array and repaint the view.

    I'm new to C/Obj-C so I don't know how else I would do this.

    Maybe I should just make my own object with float x, float y. That would work.
  4. kainjow Moderator emeritus


    Jun 15, 2000
    If you're new to C/Obj-C, making your own class is probably the easiest.
  5. lee1210 macrumors 68040


    Jan 10, 2005
    Dallas, TX
    No one mentioned that CGRect is a struct, not an NSObject. As such, it has no business in an NSArray. I'd wrap the CGRect in myCGRectWrapper or whatever you'd like to call your class. Then you can use NSArray, and make setters/getters that directly manipulate the CGRect, as well as a method that will return the CGRect for use elsewhere.

  6. teek thread starter macrumors member


    Feb 12, 2008
    Ah, this is good information. I will try making a wrapper for the CGRect. :)
  7. chown33 macrumors 604

    Aug 9, 2009
    It's not working because you're not paying attention to which types are pointers and which types aren't.

    The NSValue* is a pointer. CGRect is not.

    If you want to modify the thing pointed at, then you have to modify the thing pointed at. If there is no way to directly modify the thing pointed at, then you have to make a new thing and use its pointer in place of the other (unmodifiable) pointer.

    Draw pictures. Make diagrams.

    If it's still too confusing, think about the difference between the primitive type 'int' and the type NSNumber*. You can't put an int into an NSArray. You can, however, put an NSNumber* that was initialized to the value of an int. If you then get the NSNumber* from the NSArray, and add 20 to its intValue, storing the sum in an 'int', then think about what you need to do to put the sum back into the NSArray.

    In short, figure out how to solve the problem using the simpler values, then apply the knowledge to the more complex value (i.e. the CGRect). If necessary, write a simple test program to show how the int and NSNumber* one works.

Share This Page