Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Nicsoft

macrumors member
Original poster
Oct 17, 2009
53
0
Stockholm
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

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

Code:
@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:[COLOR="Red"]beigeImage[/COLOR]];
			}else if (ran == 1) {				
				NSLog(@"Innuti 1");
				bric2[xItr][yItr] = [[Bric alloc]initWithImage:[COLOR="Red"]brownImage[/COLOR]];
			}else if (ran == 2) {
				NSLog(@"Innuti 2");
				bric2[xItr][yItr] = [[Bric alloc]initWithImage:[COLOR="Red"]greenImage[/COLOR]];
			}else {
				NSLog(@"Innuti 3");
				bric2[xItr][yItr] = [[Bric alloc]initWithImage:[COLOR="Red"]orangeImage[/COLOR]];
			}
			
			ran = random() % 4;
		}
	}

//put the images on the screen...
	
}

@end

Thank you in advance!

Regards,
Niklas
 

Nicsoft

macrumors member
Original poster
Oct 17, 2009
53
0
Stockholm
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:mad:"beige.png" ofType:nil]];

to

beigeImage = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:mad:"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

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.