Solved

Objective-C init and initWithNumberOfSides

Posted on 2010-09-05
12
660 Views
Last Modified: 2013-11-25


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
Comment
Question by:offshorewindinwinter
  • 5
  • 4
  • 2
12 Comments
 
LVL 1

Accepted Solution

by:
XMarshall10 earned 167 total points
ID: 33610462
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
 

Author Comment

by:offshorewindinwinter
ID: 33611284
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
 
LVL 1

Expert Comment

by:XMarshall10
ID: 33615597
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
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 333 total points
ID: 33618538
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
 

Author Comment

by:offshorewindinwinter
ID: 33619431
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:offshorewindinwinter
ID: 33619452
PS. Any comments on memory use/leakage would also be great.
0
 
LVL 33

Assisted Solution

by:pgnatyuk
pgnatyuk earned 333 total points
ID: 33619568
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
 

Author Comment

by:offshorewindinwinter
ID: 33620183
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
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 33621155
You are right. In this short program you can do everything without the xib-file at all.
0
 

Author Closing Comment

by:offshorewindinwinter
ID: 33747618
Thanks for your help
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 33748320
You are welcome
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now