offshorewindinwinter
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);
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Here is all the code ... any other feedback about my code in general would also be very helpful.
Thanks again, Neil
Screen-shot-2010-09-07-at-12.35..png
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
Screen-shot-2010-09-07-at-12.35..pngScreen-shot-2010-09-07-at-12.35..png
ASKER
PS. Any comments on memory use/leakage would also be great.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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?
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.
ASKER
Thanks for your help
You are welcome
ASKER
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.