Octave1
Octave1

Reputation: 525

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 :)

Upvotes: 1

Views: 159

Answers (2)

glogic
glogic

Reputation: 4092

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

Upvotes: 3

zaph
zaph

Reputation: 112873

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.

Upvotes: 2

Related Questions