1

I'd like to create a property made by an array of CGRect pointers, the number is not defined at the beginning, so I'd like to create a pointer of to a zone o memory that contains the beginning of this array of pointer. It seems quite difficult, I've seen different answer and basing my solution on that.
So far I've writtent that:

@interface ViewController ()
@property (assign) CGRect * rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController



- (CGRect *) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect*)*count);
    for (int i = 0; i<count; i++) {
        CGRect currentFrame = ((UIView*)_hotspots[i]).frame;
        _rectArray[i] = &currentFrame;
    }

    return _rectArray;
}
@end

but the compiler complains telling me that the assignment is not correct.

I'm guessing that probably the correct variable is not a CGRect * rectArray, but a double indirection CGRect ** rectArray.
Is that correct?
[UPDATE]
Actually it doesn't make sense what I want to do... because the property -frame return a copy of CGRect and not a pointer to it, so my idea to have direct and fast access to that is gone.

5
  • Is this the full class definition? Seems like there is something missing... Commented May 22, 2013 at 11:35
  • Of course not...I've cut al the unnecessary methods Commented May 22, 2013 at 11:35
  • @Andrea What you want to do "breaks encapsulation"; it exposes details of UIView's internal implementation, instead of properly using the accessor provided. You shouldn't store a pointer to what an accessor returns, you should always use the accessor directly. Commented May 22, 2013 at 12:35
  • By the way, the frame on UIView is not a piece of memory. UIView stores only bounds and center. frame is only a conventient accessor which merges the two properties together. Commented May 22, 2013 at 12:57
  • @wilsonmichaelpatrick yes it was wrong conceptually, I guess that is because I'm sick and I'm tripping with my mind. Thanks for you comment Commented May 22, 2013 at 13:02

2 Answers 2

1

The following code accesses the rectArray correctly.

@interface ViewController ()
//array of pointers 
@property (assign) CGRect **rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController


- (CGRect **) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect*)*count);

    for (int i = 0; i<count; i++) {
        //this will never work, the frame returned from UIView is a temporary which will get released!
        CGRect currentFrame = ((UIView*)_hotspots[i]).frame;
        _rectArray[i] = &currentFrame;
    }

    return _rectArray;
}

- (void)dealloc {
   free(_rectArray);
}
@end

However, as I am writing in the comments, this won't work. [UIView frame] returns a C-struct. This behaves the same as primitive variables (NSInteger, long etc.). It gets copied. &currentFrame is a reference to your local stack variable, which will get freed when the code goes outside scope (for iteration ends, method ends). It won't do what you are expecting. Accessing the stored pointers will make your application crash.

Your expected functionality can be accomplished easily by the following two methods

- (void)setFrame:(CGRect)frame forHotspotAtIndex:(NSUinteger)index {
    UIView* hotspot = [self.hotspots objectAtIndex:index];
    hotspot.frame = frame;
}

- (CGRect)frameForHotspotAtIndex:(NSUinteger)index {
    UIView* hotspot = [self.hotspots objectAtIndex:index];
    return hotspot.frame;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes @Suthan you are completely right, I don't know why I'm messing with that, is wrong conceptually. thanks
1

If you are allocating an array of CGRects, malloc(sizeof(CGRect*)*count) is wrong as you are trying to allocate an array of pointers to CGRect.
Also when we assign CGRect to the array, we don't need to get its pointer, _rectArray[i] = currentFrame should work just fine.

The following code should work for you:

@interface ViewController ()
@property (assign) CGRect * rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController

- (CGRect *) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect)*count);
    for (int i = 0; i<count; i++) {
        CGRect currentFrame = ((UIView*)[_hotspots objectAtIndex:i]).frame;
        _rectArray[i] = currentFrame;
    }

    return _rectArray;
}
@end

1 Comment

Thanks.. but the reality was that I'd like to have an array of pointers to CGRect, I will try as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.