Accessing int value from another class - objective-c

I am having trouble accessing an int property from another class. I know this question has been asked quite a few times however none of the solutions posted in previous questions seem to work. My knowledge in xcode is basic, and I am using this project to develop my skills.
The two classes I have are: HelloWorldLayer and ClassOne. Where ClassOne states the value of int. Both are Cocos2d CCLayer classes (probably not the best class to practice inter-class value access).
ClassOne.h
#interface ClassOne : CCLayer {
int ageClass;
}
#property (nonatomic, readwrite)int ageClass;
#end
ClassOne.m
#implementation ClassOne
#synthesize ageClass = _ageClass;
-(id)init{
if((self=[super init])){
_ageClass = 10;
}
return self;
}
#end
HelloWorldLayer.h
#import "ClassOne.h"
#interface HelloWorldLayer : CCLayer <...> {
ClassOne *agePointer;
}
#property (nonatomic,assign)ClassOne *agePointer;
+(CCScene*)scene;
#end
HelloWorldLayer.m
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#import "ClassOne.h"
#implementation HelloWorldLayer
#synthesize agePointer = _agePointer;
+(CCScene*)scene...
-(id)init{
if((self=[super init])){
_agePointer.ageClass = self;
NSLog(#"ClassOne int = %#",_agePointer);
}
return self;
}
...
#end
Output Result:
"ClassOne int = (null)"
or "0" if i use "%d" token and "int = x", where the line "int x =_agePointer.ageClass;"
is used.
The result I am after is for the HelloWorldLayer NSLog to display "10", the int value defined in ClassOne.
Any wisdom and corrections on my use of language is greatly appreciated.

Ok Try This:
-(id)init
{
if((self=[super init])){
_agePointer = [[ClassOne alloc] init];
NSLog(#"ClassOne int = %d",_agePointer.ageClass);
}
return self;
}

First of all, when outputting int, always use %d instead of %# in your NSLog.
Second of all, if you are expecting to output 10, you should've instantiated the class first in your HelloWorldLayer.m:
-(id)init{
if (self = [super init]) {
_agePointer = [[ClassOne alloc] init];
NSLog(#"ClassOne int = %#",_agePointer);
}
return self;
}

Related

Objective C getter method not working for property

I was playing around with objective C. This is my code for a class I wrote , arithmetic.h:
#import <Foundation/Foundation.h>
#interface arithmetic : NSObject
#property int cur;
-(id)initWithNumber:(int)number;
#end
#implementation arithmetic
#synthesize cur;
- (instancetype)init
{
self = [super init];
if (self) {
NSLog(#"Yo, all works :D ");
}
return self;
}
-(id)initWithNumber:(int)num{
self = [super init];
if(self){
[self setCur:8] ;
}
return self;
}
#end
Note the #property int cur. I was excepting objective c to create a setCur and a getCur method as accessors and mutators for my class. However, when I run this:
arithmetic *test = [[arithmetic alloc] initWithNumber:89];
[test setCur:534];
NSLog("%i",[test getCur ]);
The first two lines work. But the last line says
No visible interface for arithmetic declares the selector 'getCur'
What is the problem ?
It is because when you declare like this in your #implementation:
#synthesize cur;
it will create getter
-(int)cur {
return _cur;
}
and also it will create a setter
-(void)setCur:(int)newCur {
_cur = newCur;
}
In summary, Objective-C getter/setter is having a pattern of propery/setPropery respectively, unlike Java that uses getProperty/setProperty.
And Objective-C getter/setter is accessed via dot(.) notation. For example
int x = obj.cur;
obj.cur = 100;

"Expected a type" error Objective C

I've asked questions on here so many times about this ruddy game that I'm trying to make. I'm working on a Text-Based adventure game. First I made it in Java because that's what I was learning the the class the game was for. Now I'm trying to learn iOS development which requires objective-c. I feel pretty comfortable with objective c after taking the Lynda Essentials course (The previous experience with Java helped of course). Anyways I'm working on this game and I'm running into a problem that seems pretty unique to objective c.
In Java when I have multiple classes they just need to be in the same directory in order for me to use them in other classes. This is not the case in Objective-C... I have to import the header files if I want to use class A in class B. Well for this game I have two custom classes, a Location class and an Exit class. The Location class needs to know about what Exits it has (So I have to import Exit.h if I want to use them) and the exits need to know which location it's connected to (So I have to import Location.h). It seems that I can't do this because of something called Circular Referencing (or something like that). However, if I don't do this then I get an "Expected a type" error. So I have no idea what to do. I'll show the code below.
Exit.h
#import <Foundation/Foundation.h>
#import "Location.h"
#define NORTH 0
#define SOUTH 1
#define EAST 2
#define WEST 3
#interface Exit : NSObject
#property NSString * dirName;
#property NSString * dirShortName;
#property int direction;
#property Location * connection;
-(id)initWithConnection:(Location *) loc andDirection:(int) dir;
#end
Exit.m
#import "Exit.h"
#implementation Exit
#synthesize dirName;
#synthesize dirShortName;
#synthesize direction;
#synthesize connection;
-(id)initWithConnection:(Location *)loc andDirection:(int)dir {
self = [super init];
if(self) {
direction = dir;
switch(direction) {
case 0:
dirName = #"North";
dirShortName = #"N";
break;
case 1:
dirName = #"South";
dirShortName = #"S";
break;
case 2:
dirName = #"East";
dirShortName = #"E";
break;
case 3:
dirName = #"West";
dirShortName = #"W";
break;
}
connection = loc;
}
return self;
}
#end
Location.h
#import <Foundation/Foundation.h>
#interface Location : NSObject
#property NSString * title;
#property NSString * desc;
#property NSMutableDictionary * exits;
#property BOOL final;
-(id) initWithTitle:(NSString *) _title;
-(id) initWithDescription:(NSString *) _desc;
-(id) initWithTitle:(NSString *) _title andDescription:(NSString *) _desc;
-(void) addExit:(Exit *) _exit;
#end
Location.m
#import "Location.h"
#implementation Location
#synthesize title;
#synthesize desc;
#synthesize exits;
#synthesize final;
-(void) addExit:(Exit *) _exit {
NSString * tmpName = [_exit dirName];
NSString * tmpShortName = [_exit dirShortName];
[exits setObject:tmpName forKey:tmpShortName];
}
-(NSString *)description {
NSString * tmp = [[NSString alloc] initWithFormat:#"%#\n%#\n",self.title,self.desc];
for(NSString * s in exits) {
[tmp stringByAppendingFormat:#"\n%#",s];
}
return tmp;
}
// Initialization Methods
-(id) init {
self = [super init];
if(self) {
title = #"";
desc = #"";
}
return self;
}
-(id) initWithTitle:(NSString *) _title {
self = [super init];
if(self) {
title = title;
desc = #"";
exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil];
}
return self;
}
-(id) initWithDescription:(NSString *) _desc {
self = [super init];
if(self) {
title = #"";
desc = desc;
exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil];
}
return self;
}
-(id)initWithTitle:(NSString *) _title andDescription:(NSString *)_desc {
self = [super init];
if(self) {
title = title;
desc = desc;
exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil];
}
return self;
}
#end
I'm really hoping I'm not trying to do something that's impossible. I also hope my code can be made sense of and I'm not making too much of a fool of myself here ;) thanks for any advice.
EDIT:
Just reread and now understand better, you need to do #class Exit; to define the Exit class in the Location header and then you can do the same #class Location; in the Exit header in order to tell the compiler that the classes are defined. Then if you were to reference those classes in the implementation files (.m) then you would import the Exit.h file and Location.h file respectively
The rule of thumb I have started to follow, which seemed counter-intuitive to me at first is this:
In your header files, use "forward declarations" prolifically with only 2 exceptions:
headers for classes you are extending, and headers for protocols you are conforming to; and only do #import directives in your .m files.
This should resolve the circular reference error; it did mine.
See here, and do a 'find' for the word "forward".

imageitem class define

i need to build an application that define an array that should be made of image items.
every image iten has an image, a name and a photographer name.
i build my image item class and i want you to check if my define is correct and good(i just start to learn objective c).
i want you to emphasize on the set's methods.
here is the photoitem.h:
#import <Foundation/Foundation.h>
#interface photoItem : NSObject
{
UIImage *imageView;
NSString *photoNameLabel;
NSString *photographerNameLabel;
UIButton *viewPhoto;
}
#property(readonly) NSString *name;
#property(readonly) NSString *nameOfPhotographer;
#property(readonly) UIImage *imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer: (NSString*)photographerName;
#end
here is my photoitem.m:
#import "photoItem.h"
#implementation photoItem
#synthesize name;
#synthesize nameOfPhotographer;
#synthesize imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName
{
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
return self;
}
-(void) setName:(NSString *)name
{
photoNameLabel = name;
}
-(void) setNameOfPhotographer:(NSString *)nameOfPhotographer
{
photographerNameLabel = nameOfPhotographer;
}
-(void)setImageItem:(UIImage *)imageItem
{
imageView = imageItem;
}
#end
i hope you could fix my errors(if there are some).
thanks.
Two problems come to mind:
1) -(id)makePhotoItemWIthPhoto:name:photographer: might be better as -(id)initWithPhoto:name:photographer:. Otherwise the caller needs to alloc and init an object first so that self is valid, then call your method. At that point, the return of self doesn't make sense.
Example:
-(idinitWithPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName {
self = [super init];
if (self) {
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
}
return self;
}
2) The three readonly properties don't seem to have any purpose since they have no connection to the variables that you initialize in the makePhotoItemWIthPhoto: method.

Calling classes from seperate class in a program

I have an xcode project which has 2 classes - Stem & Player, I'm trying to ensure my code is solid from an object-orientated perspective, I believe it's acceptable programming practice for my Player Class to access information in my Stem Class.
I want to access indices from an array in stem - I can do this from my view controller using
stem.index[i]
when I try to do this from player I'm not allowed as stem is undeclared. I've tried importing Stem.h into my Player.m file & declaring stem in player (similar to how one does this in the view controller), only to get errors (expected specifier-qualifier-list before 'Stem').
What's the correct way to do this? Please excuse any loose use of terminology as I'm relatively new to this. Thanks in advance :)
Edit
Here is some code that might shed some light on things, In the viewController I declare stem & player
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>
#import "Stem.h"
#import "Player.h"
#interface TestApp_v1ViewController : UIViewController {
Stem *stem;
Player *player;
I alloc & init my two objects stem & player in viewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Init Successful");
[self loadMOV];
[self setupInterface];
stem = [[Stem alloc] init];
player = [[Player alloc] init];
}
I then move to Stem.h where I declare stem again (so that stem is accessible to player when stem.h is imported to player.h - as per glogic's comment)
#import <Foundation/Foundation.h>
#interface Stem : NSObject {
int *index;
int numberOfStems;
Stem *stem;
}
#property(nonatomic,readwrite) int *index;
#property(nonatomic, retain) Stem *stem;
Player.h looks like this:
// Player.h
#import <Foundation/Foundation.h>
#import "Stem.h"
#interface Player : NSObject {
NSMutableArray *player1;
}
#property(nonatomic,retain) NSMutableArray *player1;
-(void) playAudio;
#end
Finally in Player.m I try to access the index array
#import "Player.h"
#implementation Player
#synthesize player1;
-(void)playAudio {
NSLog(#"play audio called");
NSLog(#"index[0] is: %i", stem.index[0]);
}
#end
I'm still being told that stem is undeclared, any ideas?
Edit #2 - adding bare-bones program
I hope this is considered ok but I've decided to post my program (pared down to the bare essentials). I think it may be the only way that the issue might be figured out - since a lot is going on across classes. I've been trying to get this to work for hours now arrrgh...
I alloc'd & initialised my stem & player objects in the viewController - i thought this was the best way to go about this, but maybe there is a better method.
//Part (i)
// TestApp_v1ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>
#import "Stem.h"
#import "Player.h"
#interface TestApp_v1ViewController : UIViewController {
Stem *stem;
Player *player;
}
#property(nonatomic, retain) Stem *stem;
#property(nonatomic, retain) Player *player;
#end
//Part (ii)
// TestApp_v1ViewController.m
#import "TestApp_v1ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#implementation TestApp_v1ViewController
#synthesize stem;
#synthesize player;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Init Successful");
stem = [[Stem alloc] init];
[stem loadURLs];
player = [[Player alloc] init];
[player playAudio];
int index = stem.value;
NSLog(#"r is: %i", index); //checking to see if I can get a value from the index array - this works fine, so 'value' can be accessed from the viewController
}
Here I declare an int array & the int "value" which I want to access later from my player (this is what turns out to be the problem)
//Part (iii)
// Stem.h
#import <Foundation/Foundation.h>
#interface Stem : NSObject {
NSMutableArray *urlArray;
int *index;
int value;
int numberOfStems;
Stem *stem;
}
- (void)loadURLs;
- (void)randomiseAudioForInitialPlay;
#property(nonatomic,retain) NSMutableArray *urlArray;
#property(nonatomic,readwrite) int *index;
#property(nonatomic,readwrite) int numberOfStems;
#property(nonatomic,readwrite) int value;
#property(nonatomic, retain) Stem *stem;
#end
//Part (iv)
// Stem.m
#include <stdio.h>
#import "Stem.h"
#implementation Stem
#synthesize numberOfStems;
#synthesize urlArray;
#synthesize index;
#synthesize stem;
#synthesize value;
- (void)loadURLs
{
NSLog(#"Loading URLs");
numberOfStems = 20;
urlArray = [[NSMutableArray alloc] init];
for ( int i = 1; i <= numberOfStems; i++ ) {
NSString *soundName = [NSString stringWithFormat:#"stem-%i", i];
NSString *soundPath = [[NSBundle mainBundle] pathForResource:soundName ofType:#"mp3"];
NSURL *soundFile = [[NSURL alloc] initFileURLWithPath:soundPath];
[urlArray addObject:soundFile];
[soundFile release];
}
[self randomiseAudioForInitialPlay];
}
- (void)randomiseAudioForInitialPlay
{
index = malloc(numberOfStems*sizeof(int));
for (int i = 0; i < numberOfStems; i++)
{
index[i] = i;
}
for (int i = (numberOfStems - 1); i > 0; i--)
{
int randomIndex = arc4random() % i;
int tmp = index[i];
index[i] = index[randomIndex];
index[randomIndex] = tmp;
}
value = self.index[10]; //this is what needs to be accessed later, from player
NSLog(#"value at index 10 is:%i", value);
}
#end
Here I include 'Stem.h' since player will require stem in order to return stem.value
//Part (v)
// Player.h
#import <Foundation/Foundation.h>
#import "Stem.h"
#interface Player : NSObject {
Player *player;
}
#property(nonatomic, retain) Stem *stem;
#property(nonatomic, retain) Player *player;
-(void) playAudio;
#end
This is where things go wrong, my NSLog statement tells me that value is 0, even though I can see that it's (e.g.) 14 in stem. The compiler gives no errors either.
//Part (vi)
// Player.m
#import "Player.h"
#implementation Player
#synthesize player;
#synthesize stem;
-(void)playAudio {
int value = stem.value;
NSLog(#"value is:%i", value );
}
#end
This is my first proper go at an object-orientated project so I'm learning on the job, any suggestions as to why I can't access stem.value in my Player class?
My ideas on how the various objects in such a program interact with one another (& the correct syntax) are still hazy so please forgive me for crazy n00b errors in my code :)
where are you declaring stem within player? if you are declaring it within the player.h then you will need the import of stem.h within the player.h and not player.m.
edit: yeah its still undeclared because you have stem declared in the view controller not the player. hmm seems to be afew things out of whack here. it really depends on how your code will actually work
#import Stem.h
#interface Player : NSObject {
NSMutableArray *player1;
}
#property(nonatomic,retain) NSMutableArray *player1;
#property(nonatomic,retain) Stem *stem;
-(void) playAudio;
#end
#
import "Player.h"
#implementation Player
#synthesize player1, stem = _stem;
-(void)playAudio {
NSLog(#"play audio called");
NSLog(#"index[0] is: %i", _stem.index[0]);//stem.index[0] will be a problem here as its not a c array
}
#end
and then in ur controller
player.stem = stem;
and im not sure why ur creating a stem pointer within the stem class.
#interface Stem : NSObject {
int *index;
int numberOfStems;
}
#property(nonatomic,readwrite) int *index;
and if its an array of stems you want then create that in the controller
edit : after you have the lines
player = [[Player alloc] init];
[player playAudio];
add
player.stem = stem;
you have to assign the pointer within player to the stem that you created in the view controller
The best way is to create a method in the Stem class like:
value = [stem valueAtIndex:i];
That way there is less coupling and the way the values are held in the Stem class is not exposed and can be changed later if necessary without preaching the access calls.

Using AtlasSprite as a parent class - Giving problems on propreties on the class

I am trying to have AtlasSprite as a parent class but it's giving me errors on propreties. Like it can't seem to find them: Here's the code extract.
interface:
#interface Glyph : AtlasSprite{
float eyelevel;
}
#property (readwrite,assign) float eyelevel;
-(id) initWithMgr:(id) mgr;
implementation:
#implementation Glyph
#synthesize eyelevel;
-(id) init {
if( (self=[super init] )) {
eyelevel = 0;
}
return self;
}
-(id) initWithMgr:(id) mgr{
if( (self=[super init] )) {
[self init];
self = [AtlasSprite spriteWithRect:CGRectMake(0, 0, 119, 45) spriteManager: mgr];
}
return self;
}
here are the calls to this class:
AtlasSpriteManager *mgr = AtlasSpriteManager spriteManagerWithFile:#"atlas_glyph.png" capacity:3];
Glyph *glyph = [[Glyph alloc] initWithMgr:mgr];
[glyph setEyelevel:0];
It keeps crashing for me when it hits [glyph setEyelevel:0]; , saying it doesn't recognize the selector to the instance. Any help?
Your #synthesize statement does not match your #property.
#property (readwrite,assign) float currentEyeLvlY;
But you synthesize the setter with:
#synthesize eyelevel;
You need these variables to match, or explicitly define the relationship in your #synthesize like so:
#synthesize currentEyeLvlY = eyelevel;