[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 713
  • Last Modified:

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

0
offshorewindinwinter
Asked:
offshorewindinwinter
  • 5
  • 4
  • 2
3 Solutions
 
XMarshall10Commented:
In Objective-C, the Syntax: (self = [super init]) means that you are trying to initialize your super (base) class from your subclass (derived class). Unlike C or C++, this syntax is typically different in the sense that it comes from the SmallTalk language.

Also could not understand why the @synthesize calls are commented out?? If the getter and setter functionality are commented out, you will probably not able to read from numberOfSidesLabel variable in awakeFromNib method.

-XM
0
 
offshorewindinwinterAuthor Commented:
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.
0
 
XMarshall10Commented:
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
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 
pgnatyukCommented:
It will be great to see the header files. For example, I see line where you send initWithNumberOfSides:

[polygon initWithNumberOfSides: numberOfSidesLabel.text.integerValue minimumNumberOfSides: 3 maximumNumberOfSides: 12];

in -(void)awakeFromNib, but I do not see how you created this polygon object. Is it in the nib?
Do you see the log from this  initWithNumberOfSides method?
Seems like you use a label: numberOfSidesLabel - difficult to understand without h-file, but, probably, here is the mistake.
 

0
 
offshorewindinwinterAuthor Commented:
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
0
 
offshorewindinwinterAuthor Commented:
PS. Any comments on memory use/leakage would also be great.
0
 
pgnatyukCommented:
I've not compiled your code. I'll do it a bit later. So now I can be wrong.
Please check these lines:
      IBOutlet PolygonShape *polygon;
      IBOutlet PolyDraw *polyView;
Why these are outlets?

This line:
[polygon initWithNumberOfSides: numberOfSidesLabel.text.integerValue minimumNumberOfSides: 3 maximumNumberOfSides: 12];

I do not see alloc. Maybe it should be:
polygon = [[PolygonShape alloc] initWithNumberOfSides: numberOfSidesLabel.text.integerValue minimumNumberOfSides: 3 maximumNumberOfSides: 12];

0
 
offshorewindinwinterAuthor Commented:
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?
0
 
pgnatyukCommented:
You are right. In this short program you can do everything without the xib-file at all.
0
 
offshorewindinwinterAuthor Commented:
Thanks for your help
0
 
pgnatyukCommented:
You are welcome
0

Featured Post

Become a Leader in Data Analytics

Gain the power to turn raw data into better business decisions and outcomes in your industry. Transform your career future by earning your MS in Data Analytics. WGU’s MSDA program curriculum features IT certifications from Oracle and SAS.  

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now