I am working on a programm which lets you calculate the sides in a triangle using the Pythagoras method. I recently posted my first question about this. How can I code it so that you can also work out B or A. Here is my code so far:
PythagorasCalc.m
#import "PythagorasCalc.h"
#implementation PythagorasCalc
- (double)calculatePythagorasValue {
return sqrt(A*A+B*B);
}
//Access Code
- (double)A {
return A;
}
- (void)setA: (double)value {
if(A != value) {
A = value;
}
}
- (double)B {
return B;
}
- (void)setB: (double)value {
if(B != value) {
B = value;
}
}
- (double)C {
return C;
}
- (void)setC: (double)value {
if(C != value) {
C = value;
}
}
#end
PythagorasCalc.h
#import <Cocoa/Cocoa.h>
#interface PythagorasCalc : NSObject {
#private
int A;
int B;
int C;
}
#property (nonatomic) double A;
#property (nonatomic) double B;
#property (nonatomic) double C;
- (double)calculatePythagorasValue;
#end
AppDelegate.m
#import "PythagorasCalculatorAppDelegate.h"
#implementation PythagorasCalculatorAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
calculator = [[PythagorasCalc alloc] init];
}
- (IBAction)calculateClicked:(id)sender {
double A = _ATextField.doubleValue;
double B = _BTextField.doubleValue;
double C = _CTextField.doubleValue;
calculator.A = A;
calculator.B = B;
calculator.C = C;
_CTextField.doubleValue = [calculator calculatePythagorasValue];
}
#end
AppDelegate.h
#import <Cocoa/Cocoa.h>
#import "PythagorasCalc.h"
#interface PythagorasCalculatorAppDelegate : NSObject <NSApplicationDelegate> {
//Public Calculator Object
PythagorasCalc *calculator;
}
#property (assign) IBOutlet NSWindow *window;
- (IBAction)calculateClicked:(id)sender;
#property (weak) IBOutlet NSTextField *ATextField;
#property (weak) IBOutlet NSTextField *BTextField;
#property (weak) IBOutlet NSTextField *CTextField;
#end
I have a android game ready to launch and I'm currently working on porting it to iOS.
I'm fairly new to Objective C and C in general and I'm not sure exactly how #properties and #synthesize and #imports work.
My game shares a method file called gMain. This file includes the shared methods between objects. I have an object called Fish and in that object contains a method which requires the x,y value of another object called Fish2.
I'm unsure of how to access the variables when both Fish and Fish2 share the same variable names, int x, int y.
will this work?
//Fish.h
#interface Fish
{
int x, y;
}
#property int x, y;
-(void)blah;
#end
//Fish2.h
#interface Fish2
{
int x, y;
}
#property int x, y;
#end
//Fish.m
#import Fish.h
#implementation Fish
#synthesize x, y;
-(void)blah
{
x = Fish2.x;
y = Fish2.y;
}
#end
//Fish2.m
#import Fish2.h
#implementation Fish2
#synthesize x, y;
#end
does this synthesize both xs and ys from the 2 objects?
No.
Your code won't compile. You've left out all the #interface, #implementation, and #end directives that tell the compiler what class you're talking about. A #synthesize directive will always be included between #implementation *classname* and #end, and it will only synthesize a property for the indicated class.
If you correct your code, the effect of the #synthesize should be obvious.
//Fish.h
#interface Fish
{
int x, y;
}
#property int x, y;
#end
//Fish.m
#import Fish.h
#import Fish2.h // it's not clear why you'd need this
#implementation Fish
#synthesize x, y; // creates accessors for properties x and y of class Fish
#end
I'm not sure if you are wanting to deal with a single class, with two instances, two separate classes. I'll try to give an example of each and try to explain what the code is doing.
Single Class, Two Instances
Fish.h
#interface Fish : NSObject
#property (nonatomic, assign) int x;
#property (nonatomic, assign) int y;
- (void) someMethod;
#end
So you are defining a new object called FishA and the object has 2 public properties, x and y. The 2 items in parenthisis nonatomic and assign tell the compiler extra information about the properties. Bassicaly nonatomic means not to worry about thread safty and assign means that the property is a base type, not an object.
Fish.m
#import "Fish.h"
#implementation Fish
#synthesize x = _x;
#synthesize y = _y;
- (id) init {
self = [super init];
if (self) {
// Initilize default values
// Only use the _x and _y in init
// no other place
_x = 0;
_y = 0;
}
return self;
}
- (void) someMethod {
// Set the values
self.x = 10;
self.y = 10;
// Access the values
NSLog(#"X: %d", self.x)
NSLog(#"Y: %d", self.y)
}
So the #synthesize statments will create two methods for you, one to set the value and one to get the value. In the statements above the x tells the compiler to create the methods for the x property, the _x is the name of the interal storage variable for the property. It is much better that the property and the internal storage are separatly named, it makes the code cleaner and easier to understand whats going on.
In th init method we directly set the internal variable with the initial values. The init method is generally the only place you want to access the internal variables.
Use
#import "Fish.h"
- (void) example {
Fish *fishA = [[Fish alloc] init];
Fish *fishB = [[Fish alloc] init];
fishA.x = 10;
fishB.x = 20;
[fishA someMethod];
[fishB someMethod];
}
Separate Classes
FishA.h
#interface FishA : NSObject
#property (nonatomic, assign) int x;
#property (nonatomic, assign) int y;
#property (nonatomic, assign) int size;
- (void) someMethod;
#end
FishA.m
#import "FishA.h"
#implementation FishA
#synthesize x = _x;
#synthesize y = _y;
#synthesize size = _size;
- (id) init {
self = [super init];
if (self) {
// Initilize default values
// Only use the _x and _y in init
// no other place
_x = 0;
_y = 0;
_size = 10;
}
return self;
}
- (void) someMethod {
// Set the values
self.x = 10;
self.y = 10;
// Access the values
NSLog(#"X: %d", self.x)
NSLog(#"Y: %d", self.y)
}
FishB.h
#interface FishB : NSObject
#property (nonatomic, assign) int x;
#property (nonatomic, assign) int y;
#property (nonatomic, strong) NSColor *color;
- (void) someMethod;
#end
The color propery looks a little different. Because color is an object and not a base type we need to tell the compiler how we want to handle it. The strong tells the compiler to hold on to this object untill we are done with it. The other option would be weak and that tells the compiler not to hold on to the object. Generally speaking, with objectes, use strong.
FishB.m
#import "FishB.h"
#implementation FishB
#synthesize x = _x;
#synthesize y = _y;
#synthesize color = _color;
- (id) init {
self = [super init];
if (self) {
// Initilize default values
// Only use the _x and _y in init
// no other place
_x = 0;
_y = 0;
_color = [NSColor blueColor];
}
return self;
}
- (void) someMethod {
// Set the values
self.x = 10;
self.y = 10;
// Access the values
NSLog(#"X: %d", self.x)
NSLog(#"Y: %d", self.y)
}
So I've created two separate classes, FishA has a size property and FishB has a color property. Both fish have the x and y properties. Not overly exciting but it makes the two classes different.
Use
#import "FishA.h"
#import "FishB.h"
- (void) example {
FishA *fishA = [[FishA alloc] init];
FishB *fishB = [[FishB alloc] init];
fishA.x = 10;
fishB.x = 20;
fishA.size = 50; // Works
fishB.size = 50; // Will not work
fishA.color = [NSColor redColor]; // Will not work
fishB.color = [NSColor redColor]; // Works
}
This will not work
-(void)blah
{
x = Fish2.x;
y = Fish2.y;
}
You need to create a pointer for Fish2. Something like this...
-(void)blah
{
Fish2 *selectedFish = //wherever the instance of the fish is.
x = selectedFish.x;
y = selectedFish.y;
}
If Fish creates an instance of fish2 maybe doing something like this would be more helpful.
-(void)blahWithFish:(Fish2)currentFish
{
x = currentFish.x;
y = currentFish.y;
}
If you do something like that you can pass the fish to this method.
Also is there a reason for fish2? Are you not just creating 2 fish objects? Do they perform the same task? Maybe fish2 should inherit from Fish?
Does that help?
I'm working on one simple objective-c program which contain categories. My class .h:
#import <Foundation/Foundation.h>
#interface Fraction : NSObject
#property int numerator, denominator;
-(void)setNumerator:(int)n andDenominator:(int)d;
#end
In .m file I synthesized my numerator and denominator. In main.m created category of my Fraction class:
#import "Fraction.h"
#interface Fraction (MathOps)
-(Fraction *) add: (Fraction *) f;
#end
#implementation Fraction (MathOps)
-(Fraction *) add: (Fraction *) f
{
// To add two fractions:
// a/b + c/d = ((a*d) + (b*c)) / (b * d)
Fraction *result = [[Fraction alloc] init];
result.numerator = (numerator * f.denominator) +
(denominator * f.numerator);
result.denominator = denominator * f.denominator;
[result reduce];
return result;
}
#end
But my program does not see numerator and denominator in category's implementation section. Error "Use of undeclared identifier 'numerator'(the same for denominator). What am I doing wrong?
Use the properties instead of using the ivars directly:
result.numerator = (self.numerator * f.denominator) + (self.denominator * f.numerator);
result.denominator = self.denominator * f.denominator;
The instance variables aren't visible to your category because they're not declared in Fraction's interface -- they're only created when you #synthesize them in your implementation. That leads to the other possible solution, which is to declare the instance variables in Fraction's interface:
#interface Fraction : NSObject {
int numerator;
int denominator;
}
#property int numerator, denominator;
-(void)setNumerator:(int)n andDenominator:(int)d;
#end
Error: Accessing unknown getter method?
Thanks...
#import <Foundation/Foundation.h>
#interface puppy : NSObject {
int mack;
int jack;
}
-(puppy *) waldo: (puppy *) f;
-(void) setMack: (int) m;
-(void) setJack: (int) j;
#end
///////////////////////////////////////////////////
#import "puppy.h"
#implementation puppy
-(void) setJack: (int) j{
jack = j;
}
-(void) setMack: (int) m{
mack = m;
}
-(puppy*) waldo: (puppy *) f{
return (f.jack + f.mack); // Error: <-- Accessing unknown "jack" getter method
// Error: <-- Accessing unknown "mack" getter method
}
You have not specified getter method for jack and mack. Instead of writing own getter/setter you can use property for them.
#interface puppy : NSObject {
int mack;
int jack;
}
-(puppy *) waldo: (puppy *) f;
// use property
#property (nonatomic, assign) int mack;
#property (nonatomic, assign) int jack;
#end
#implementation puppy
#synthesize jack, mack;
-(puppy*) waldo: (puppy *) f{
return (f.jack + f.mack);
}
#end
You do not need those set methods now. Both getters and setter are synthesized for you. And not asked in the question, you should return int from method waldo.
You haven't implemented the methods jack and mack.
- (int) jack { return jack; }
- (int) mack { return mack; }
But I'd recommend just using #property and #synthesize with no ivar.
When you do f.jack, it translates to [f jack]. You need to add a - (int)jack method to your interface for this to work. Poorly worded perhaps, I also meant the method needs to be implemented. Same is the case of mack
But that said, dot notation is for properties. Isn't apt.
It would be easier if you defined properties for mack and jack and synthesized those methods.
Whenever I call the doSomething function my program crashes. The actual code as a bit of array bounds checking, so I know that's not an issue.
myClass.h
#import <Foundation/Foundation.h>
#interface myClass : NSObject {
BOOL **myMatrix;
}
#property(readwrite) BOOL **myMatrix;
-(myClass*)initWithWidth: (int)w andHeight: (int)h;
-(void)doSomething;
+(BOOL **) createMatrixWithHeight: (int)h andWidth: (int)w;
#end
myClass.m
#import "myClass.h"
#import <Foundation/Foundation.h>
#implementation myClass
#synthesize myMatrix;
-(myClass*)initWithWidth: (int)w andHeight: (int)h {
self = [super init];
myMatrix = [myClass createMatrixWithHeight: h andWidth: w];
return self;
}
-(void)doSomething{
myMatrix[2][2] = YES;
}
+(BOOL **) createMatrixWithHeight: (int)h andWidth: (int)w{
BOOL **newMatrix;
newMatrix = malloc(w * sizeof(BOOL *));
int i;
for(i = 0; i < w; i++){
newMatrix[i] = malloc(h * sizeof(BOOL));
}
return newMatrix;
}
#end
There must be some important difference between the code you posted and the code in your program, because I copied and pasted this in to a program and it ran fine without crashing.
So the answer to your question is this: just like in the code you posted.
This:
newMatrix = malloc(w * sizeof(BOOL *));
int i;
for(i = 0; i < w; i++){
newMatrix[i] = malloc(h * sizeof(BOOL));
}
is not a 2-dimensional array. It's an array of pointers to array.
A 2-dimensional array would be allocated as:
newMatrix = malloc(w * h * sizeof(BOOL));
See http://en.wikipedia.org/wiki/C_syntax#Multidimensional_arrays