Link to home
Start Free TrialLog in
Avatar of offshorewindinwinter
offshorewindinwinterFlag for Canada

asked on

Objective-C init and initWithNumberOfSides



I am puzzled why I cannot read numberOfSidesLabel in awakeFromNib. The program works fine once the Up or Down buttons are pressed.

I also obviously need a better understanding of how init methods work. At the moment I am getting the results from init even tho I don't explicitly call it.

I am not sure why and when I need to use if (self = [super init]).

See output below


2010-09-05 22:58:25.192 Poly[6778:207] awakeFromNib numberOfSidesLabel: (null)
2010-09-05 22:58:25.193 Poly[6778:207] awakeFromNib numberOfSides:0
2010-09-05 22:58:25.194 Poly[6778:207] updateInterface numberOfSides: 0
2010-09-05 22:58:25.202 Poly[6778:207] initWithNumberOfSides val: 3
2010-09-05 22:58:25.203 Poly[6778:207] setNumberOfSides numberOfSides: 3
2010-09-05 22:58:25.203 Poly[6778:207] initWithNumberOfSides numberOfSides: 3
2010-09-05 22:58:25.204 Poly[6778:207] init numberOfSides: 3

Thanks for your help,

Neil

//
//  PolygonShape.m
//  
//
//  Created by Neil Bragg on 10-08-17.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "PolygonShape.h"


@implementation PolygonShape
- (int) numberOfSides {
	return numberOfSides;
}
- (void)setNumberOfSides: (int)val {
	if (val >= [self minimumNumberOfSides] && val <= [self maximumNumberOfSides]) {
		numberOfSides = val;
		NSLog(@"setNumberOfSides numberOfSides: %d", numberOfSides);
	}
	else {
		NSLog(@"numberOfSides out of range: %d is not between %d and %d", val, [self minimumNumberOfSides], [self maximumNumberOfSides]);
	}
}
- (int) minimumNumberOfSides {
	return minimumNumberOfSides;
}
- (void)setMinimumNumberOfSides: (int)min {
	if (min > 2) {
		minimumNumberOfSides = min;
	}
	else {
		NSLog(@"minimumNumberOfSides out of range: less than or equal to 2");
	}
}
- (int) maximumNumberOfSides {
	return maximumNumberOfSides;
}
- (void)setMaximumNumberOfSides: (int)max {
	if (max <= 12 && max > 2) {
		maximumNumberOfSides = max;
	}
	else {
		NSLog(@"maximumNumberOfSides out of range: greater than 12 or less than or equal to 2");
	}
}
//The formula for computing the internal angle of a regular polygon in degrees is 
//(180 * (numberOfSides - 2) / numberOfSides).
- (float)angleInDegrees {
	NSLog(@"angleInDegrees: %0.3f",(180.0 * (self.numberOfSides - 2) / self.numberOfSides));
	return 180.0 * (self.numberOfSides - 2) / self.numberOfSides;
}

- (float)angleInRadians {
	return (M_PI * ([self numberOfSides] - 2.0) / [self numberOfSides]);
}

- (NSString *) name {
	NSString *name;
	switch ([self numberOfSides])
	{
		case 3:
			name = @"triangle";
			break;
		case 4:
			name = @"square";
			break;
		case 5:
			name = @"pentagon";
			break;
		case 6:
			name = @"hexagon";
			break;
		case 7:
			name = @"heptagon";
			break;
		case 8:
			name = @"octagon";
			break;
		case 9:
			name = @"nonagon";
			break;
		case 10:
			name = @"decagon";
			break;
		case 11:
			name = @"hendecagon";
			break;
		case 12:
			name = @"dodecagon";
			break;
		default:
			name = @"no name";
			NSLog (@"name: out of range");
			break;
	}
	[name autorelease];
	return name;
}
- (id)initWithNumberOfSides:(int)val minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {
//	if (self = [super init]) {
//		NSLog(@"initWithNumberOfSides numberOfSides: %d", [self numberOfSides]);
		NSLog(@"initWithNumberOfSides val: %d", val);
		[self setMinimumNumberOfSides:min];
		[self setMaximumNumberOfSides:max];
		[self setNumberOfSides:val];
		NSLog(@"initWithNumberOfSides numberOfSides: %d", [self numberOfSides]);
//	}
	return self;
}
- (id)init {
	if (self = [super init]){
		self = [self initWithNumberOfSides: 3 minimumNumberOfSides: 3 maximumNumberOfSides: 12];
	}
	NSLog(@"init numberOfSides: %d", [self numberOfSides]);
	return self;
}

- (NSString *)description{
	return [NSString stringWithFormat: @"A %d-sided polygon is called a %@. It has angles of %.2f degrees (%.6f radians).",[self numberOfSides], [self name], [self angleInDegrees], [self angleInRadians]];
}
- (void)dealloc{
	[super dealloc];
	NSLog(@"dealloc");
}

@end


//
//  PolyViewController.m
//  Poly
//
//  Created by Neil Bragg on 10-09-05.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "PolyViewController.h"
#import "PolygonShape.h"
#import "PolyDraw.h"

@implementation PolyViewController

//@synthesize upButton;
//@synthesize downButton;
//@synthesize numberOfSidesLabel;
//@synthesize nameLabel;
//@synthesize polyView;

-(IBAction)up:(id)sender {
	[self updateInterface: 1];
}

-(IBAction)down:(id)sender {
	[self updateInterface: -1];
}

- (void)awakeFromNib {
	NSLog(@"awakeFromNib numberOfSidesLabel: %@", numberOfSidesLabel.text);
	[polygon initWithNumberOfSides: numberOfSidesLabel.text.integerValue minimumNumberOfSides: 3 maximumNumberOfSides: 12];
	NSLog(@"awakeFromNib numberOfSides:%d", polygon.numberOfSides);
	[self updateInterface: 0];
}
 
- (void)updateInterface: (int)val {
	polygon.numberOfSides += val;
	NSLog(@"updateInterface numberOfSides: %d", polygon.numberOfSides);
	numberOfSidesLabel.text = [NSString stringWithFormat:@"%d",polygon.numberOfSides];
	nameLabel.text = polygon.name;
	polyView.value = polygon.numberOfSides;
	[polyView setNeedsDisplay];
	downButton.enabled = (polygon.numberOfSides + val >= polygon.minimumNumberOfSides);
	upButton.enabled = (numberOfSidesLabel.text.integerValue + val <= polygon.maximumNumberOfSides);
 }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of XMarshall10
XMarshall10

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of offshorewindinwinter

ASKER

Thanks for your help ...

It didn't make any difference whether they were commented out or not (ie I got exactly the same result). You can see in a later line that I am able to set the label value successfully (even with these commented out).

As I said this program works except:
1. The init methods don't work as expected. The call to initWithNumberOfSides actually returns the values I have established in the init method ??

and

2. I cannot read the label value to set the initial conditions from the label. As you can see from the output when read in awakeFromNib it returns 0.even tho it is set to 5 in Interface Builder.
Avatar of XMarshall10
XMarshall10

Hi,If it is possible and OK with you, can you send me the zip of the xCode project files, I can run it at my end and check. My mail id: --XM
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here is all the code ... any other feedback about my code in general would also be very helpful.

Thanks again, Neil
//
//  PolygonShape.h
//  
//
//  Created by Neil Bragg on 10-08-17.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface PolygonShape : NSObject {

// instance variables 

	int numberOfSides;
	int minimumNumberOfSides;
	int maximumNumberOfSides;
	
}


- (int)numberOfSides;
- (void)setNumberOfSides:(int)val;
- (int)minimumNumberOfSides;
- (void)setMinimumNumberOfSides:(int)min;
- (int)maximumNumberOfSides;
- (void)setMaximumNumberOfSides:(int)max;
- (float)angleInDegrees;
- (float)angleInRadians;
- (NSString *)name;
- (id)init;
- (id)initWithNumberOfSides:(int)val minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;
- (NSString *)description;
- (void)dealloc;

@end
//
//  PolygonShape.m
//  
//
//  Created by Neil Bragg on 10-08-17.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "PolygonShape.h"


@implementation PolygonShape
- (int) numberOfSides {
	return numberOfSides;
}
- (void)setNumberOfSides: (int)val {
	if (val >= [self minimumNumberOfSides] && val <= [self maximumNumberOfSides]) {
		numberOfSides = val;
		NSLog(@"setNumberOfSides numberOfSides: %d", numberOfSides);
	}
	else {
		NSLog(@"numberOfSides out of range: %d is not between %d and %d", val, [self minimumNumberOfSides], [self maximumNumberOfSides]);
	}
}
- (int) minimumNumberOfSides {
	return minimumNumberOfSides;
}
- (void)setMinimumNumberOfSides: (int)min {
	if (min > 2) {
		minimumNumberOfSides = min;
	}
	else {
		NSLog(@"minimumNumberOfSides out of range: less than or equal to 2");
	}
}
- (int) maximumNumberOfSides {
	return maximumNumberOfSides;
}
- (void)setMaximumNumberOfSides: (int)max {
	if (max <= 12 && max > 2) {
		maximumNumberOfSides = max;
	}
	else {
		NSLog(@"maximumNumberOfSides out of range: greater than 12 or less than or equal to 2");
	}
}
//The formula for computing the internal angle of a regular polygon in degrees is 
//(180 * (numberOfSides - 2) / numberOfSides).
- (float)angleInDegrees {
	NSLog(@"angleInDegrees: %0.3f",(180.0 * (self.numberOfSides - 2) / self.numberOfSides));
	return 180.0 * (self.numberOfSides - 2) / self.numberOfSides;
}

- (float)angleInRadians {
	return (M_PI * ([self numberOfSides] - 2.0) / [self numberOfSides]);
}

- (NSString *) name {
	NSString *name;
	switch ([self numberOfSides])
	{
		case 3:
			name = @"triangle";
			break;
		case 4:
			name = @"square";
			break;
		case 5:
			name = @"pentagon";
			break;
		case 6:
			name = @"hexagon";
			break;
		case 7:
			name = @"heptagon";
			break;
		case 8:
			name = @"octagon";
			break;
		case 9:
			name = @"nonagon";
			break;
		case 10:
			name = @"decagon";
			break;
		case 11:
			name = @"hendecagon";
			break;
		case 12:
			name = @"dodecagon";
			break;
		default:
			name = @"no name";
			NSLog (@"name: out of range");
			break;
	}
	[name autorelease];
	return name;
}
- (id)initWithNumberOfSides:(int)val minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {
//	if (self = [super init]) {
//		NSLog(@"initWithNumberOfSides numberOfSides: %d", [self numberOfSides]);
		NSLog(@"initWithNumberOfSides val: %d", val);
		[self setMinimumNumberOfSides:min];
		[self setMaximumNumberOfSides:max];
		[self setNumberOfSides:val];
		NSLog(@"initWithNumberOfSides numberOfSides: %d", [self numberOfSides]);
//	}
	return self;
}
- (id)init {
	if (self = [super init]){
		self = [self initWithNumberOfSides: 3 minimumNumberOfSides: 3 maximumNumberOfSides: 12];
	}
	NSLog(@"init numberOfSides: %d", [self numberOfSides]);
	return self;
}

- (NSString *)description{
	return [NSString stringWithFormat: @"A %d-sided polygon is called a %@. It has angles of %.2f degrees (%.6f radians).",[self numberOfSides], [self name], [self angleInDegrees], [self angleInRadians]];
}
- (void)dealloc{
	[super dealloc];
	NSLog(@"dealloc");
}

@end
//
//  PolyViewController.h
//  Poly
//
//  Created by Neil Bragg on 10-09-05.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "PolygonShape.h"
#import "PolyDraw.h"

@interface PolyViewController : UIViewController {
	IBOutlet UIButton *upButton;
	IBOutlet UIButton *downButton;
	IBOutlet UILabel *numberOfSidesLabel;
	IBOutlet UILabel *nameLabel;
	IBOutlet PolygonShape *polygon;
	IBOutlet PolyDraw *polyView;
}
- (IBAction)down:(id)sender;
- (IBAction)up:(id)sender;
- (void)updateInterface: (int)value;

//@property (retain, nonatomic) UIButton *upButton;
//@property (retain, nonatomic)  UIButton *downButton;
//@property (retain, nonatomic) UILabel *numberOfSidesLabel;
//@property (retain, nonatomic) UILabel *nameLabel;
//@property (retain, nonatomic)  PolyDraw *polyView;

@end

//
//  PolyViewController.m
//  Poly
//
//  Created by Neil Bragg on 10-09-05.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "PolyViewController.h"
#import "PolygonShape.h"
#import "PolyDraw.h"

@implementation PolyViewController

//@synthesize upButton;
//@synthesize downButton;
//@synthesize numberOfSidesLabel;
//@synthesize nameLabel;
//@synthesize polyView;

-(IBAction)up:(id)sender {
	[self updateInterface: 1];
}

-(IBAction)down:(id)sender {
	[self updateInterface: -1];
}

- (void)awakeFromNib {
	NSLog(@"awakeFromNib numberOfSidesLabel: %@", numberOfSidesLabel.text);
	[polygon initWithNumberOfSides: numberOfSidesLabel.text.integerValue minimumNumberOfSides: 3 maximumNumberOfSides: 12];
	NSLog(@"awakeFromNib numberOfSides:%d", polygon.numberOfSides);
	[self updateInterface: 0];
}
 
- (void)updateInterface: (int)val {
	polygon.numberOfSides += val;
	NSLog(@"updateInterface numberOfSides: %d", polygon.numberOfSides);
	numberOfSidesLabel.text = [NSString stringWithFormat:@"%d",polygon.numberOfSides];
	nameLabel.text = polygon.name;
	polyView.value = polygon.numberOfSides;
	[polyView setNeedsDisplay];
	downButton.enabled = (polygon.numberOfSides + val >= polygon.minimumNumberOfSides);
	upButton.enabled = (numberOfSidesLabel.text.integerValue + val <= polygon.maximumNumberOfSides);
 }
 

/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/


/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

@end
//
//  PolyDraw.h
//  Poly
//
//  Created by Neil Bragg on 10-09-05.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface PolyDraw : UIView {

	float value;
}

-(void)setValue:(float)val;

@end
//
//  PolyDraw.m
//  Poly
//
//  Created by Neil Bragg on 10-09-05.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "PolyDraw.h"
#import "PolygonShape.h"


@implementation PolyDraw

-(void)setValue:(float)val {
	self->value = val;
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
	
	if(self->value != 0 ) {
		float sectorDeg = 0.0;
		int x = 140;
		int y = 140;
		int r = 120;
	
		CGContextRef ctx = UIGraphicsGetCurrentContext();
		CGContextSetRGBStrokeColor(ctx, 1.0, 1.0, 1.0, 1.0);
		CGContextSetLineWidth(ctx, 2.0);
	
		sectorDeg = 2 * M_PI / self->value;
		//NSLog(@"degrees, %.3f", sectorDeg);
		int i;
		for (i = 1; i <= self->value; i++) {
			//NSLog(@"i: %d", i);
			CGContextSetRGBFillColor(ctx, 1.0-i/self->value, 1.0-(i-2)/self->value, 1.0-(i-3)/self->value, 1.0);
			CGContextMoveToPoint(ctx, x, y);
			CGContextAddArc(ctx, x, y, r, (i-1.0) * sectorDeg, i*sectorDeg,0);
			CGContextClosePath(ctx);
			CGContextFillPath(ctx);
		}
	}
}

- (void)dealloc {
    [super dealloc];
}


@end

Open in new window

Screen-shot-2010-09-07-at-12.35..png
Screen-shot-2010-09-07-at-12.35..png
PS. Any comments on memory use/leakage would also be great.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes I did correct this init statement myself and yes it helped :)

I have also realised that I should be using viewDidLoad rather than awakeFromNib ... apparently labels etc are not available at "awakeFromNib" time. Does this make sense to you?
You are right. In this short program you can do everything without the xib-file at all.
Thanks for your help
You are welcome