PDA

View Full Version : Scope of variables? Doesn't manage to instantiate variables properly




Nicsoft
Oct 27, 2009, 10:44 AM
Hello,

Another beginner's question...

I am using Interface Builder to create a UIView. I want to instantiate some UIImages by loading images from file before drawRect is called.

I am trying to do this in the awakeFromNib method. The methods is called before drawRect, but it seems like the UIImages is not properly instantiated since the application crasches as soon as I am trying to use the images.

If I instantiate the UIImages in the beginning of drawRect, no problem occurs.

I did copy/paste the important parts of the code below.

I include my BoardView.h

@interface BoardView : UIView {

Bric *brics[13][9];
UIImage *orangeImage;
UIImage *brownImage;
UIImage *greenImage;
UIImage *beigeImage;

}

- (id)initWithFrame:(CGRect)frame;

- (void)awakeFromNib;

@end

and BoardView.m file


@implementation BoardView
- (void)awakeFromNib{
NSLog(@"Inside awakeFromNib");
beigeImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"beige.png" ofType:nil]];
brownImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"brown.png" ofType:nil]];
greenImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"green.png" ofType:nil]];
orangeImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"orange.png" ofType:nil]];

}

- (void)drawRect:(CGRect)rect {

CGPoint cp2 = CGPointMake(x2, 20);

Bric *bric2[13][9];

srandom(time(0));
int ran = random() % 4;


for (int xItr = 0; xItr < 13; xItr++) {
for (int yItr=0; yItr < 9; yItr++) {
NSLog(@"Integer %i", ran);
if (ran == 0) {
NSLog(@"Innuti 0");
bric2[xItr][yItr] = [[Bric alloc]initWithImage:beigeImage];
}else if (ran == 1) {
NSLog(@"Innuti 1");
bric2[xItr][yItr] = [[Bric alloc]initWithImage:brownImage];
}else if (ran == 2) {
NSLog(@"Innuti 2");
bric2[xItr][yItr] = [[Bric alloc]initWithImage:greenImage];
}else {
NSLog(@"Innuti 3");
bric2[xItr][yItr] = [[Bric alloc]initWithImage:orangeImage];
}

ran = random() % 4;
}
}

//put the images on the screen...

}

@end

Thank you in advance!

Regards,
Niklas



robbieduncan
Oct 27, 2009, 11:13 AM
Niklas go and read the Memory Management Guide for Cocoa (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html). As a hint you are not using a method with init or copy in the name so the objects are autoreleased...

Nicsoft
Oct 28, 2009, 03:37 AM
Thanks! Actually, I did read it, but unfortunately, it's not sitting in my back-bone yet...

So, the solution to the problem is that I didn't retain (or copy) the image, just stored it as a weak reference and, hence, it is autoreleased when the method ends. Hope I got it right there, please correct me if not.

In order to make it work I changed each row similar to this

beigeImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"beige.png" ofType:nil]];

to

beigeImage = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"beige.png" ofType:nil]] retain];

If you want to keep a copy of the image, just use "copy" instead of "retain" (and then changes to the original image want effect the copy).

Hope it helps someone else out there.

/Niklas

robbieduncan
Oct 28, 2009, 04:20 AM
So, the solution to the problem is that I didn't retain (or copy) the image, just stored it as a weak reference and, hence, it is autoreleased when the method ends.

Mostly right. You could also use an init method to get a retained object. And autoreleased objects probably live longer than that method, but not longer than the current iteration of the runloop.