1

I have one Class called "System" it contains some variables and two arrays and I need to access this from two other classes which should be able to read and write that variables Im a total Beginner so its pretty possible that i already did some mistakes.

System.h

@interface System : UIViewController{

float length_of_one_hour; 
float length_of_first_break;
float length_of_second_break;
float length_of_lunch_break;
float length_of_shortned_hour;
float school_begin;

int school_end[5];
float school_length[5]; 

}

About_now.m

- (void)read_school_end_monday{

school_end_label.text=[NSString stringWithFormat:@"%i", school_end[0]];

}

Settings.m

- (IBAction)set_school_end_monday{

school_end[0]= [school_end_on_mondays_textfield.text intValue];

}

But i don't know what to write in System.h and About_now.m that the variables are saved in System class and can be accessed from anywhere. And Yes I already tried @public and extern. BTW I need to have an array for the school_end because I'll calculate it (in use of length of an hour and when school actually starts etc.) with a function which already works but i need to access the variables from the About_now class afterwards.

Hope there is someone who can help me. Thanks

ferdyyy
  • 515
  • 4
  • 16
  • There is a syntax error in your `About_now.m`: you are missing a closing bracket `]` before semicolon. – Sergey Kalinichenko Apr 26 '12 at 20:37
  • oh yea that's true but I'm not actually using that code anymore. I'm using the one you wrote. And there it's giving me that error message. The only place it works is in the SystemModel class itself. – ferdyyy Apr 26 '12 at 20:47

4 Answers4

0

You have many design options for doing that:

  1. create a global System object;

  2. make the System class a Singleton;

  3. define the System class interface so that it offers accessors methods for its "properties" at the class level (vs. object level).

  4. instantiate System as it is now and pass it as a initialization parameter to the other two classes.

Now, in more detail:

(1) declare:

     extern System* globalSystemObject;

in System.h; then define:

static System* globalSystemObject = nil;

in System.m. Don't forget to initialize globalSystemObject somewhere in your code:

globalSystemObject = [[System alloc] init];

Doing like that, you can use globalSystemObject from any file which imports System.h.

(2) have a look here for details about implementing a singleton class. Keep in mind that many people suggest against using Singleton (if it is only a way to "hide" a global variable). In this specific case, considering the semantics of a class called System, I would say a Singleton is the best option for you.

(3) your class might look like this:

    @interface System : UIViewController{
    }
    +(float)length_of_one_hour;
    +(void)set_length_of_one_hour:(float)length;

    +(float)length_of_first_break;
    +(void)length_of_first_break:(float)length;

    ...
    @end

You would implement those variable in the .m file by means of static variables like in 1.

(4) this is pretty straightforward. The only thing is that you have to create the System instance and those of the other two classes in the same scope:

System* system = [[System alloc] init];
about_now* anow = [[about_now alloc] initWithSystemInstance:system];
...

The system parameter would be stored inside an ivar (or property) of about_now.

Doing like that you avoid altogether the use of global variables (even those hidden behind the Singleton mask).

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
  • and how would System look like as a global object ? – ferdyyy Apr 26 '12 at 20:09
  • Worth noting for future readers : Making variables global is generally frowned upon as it makes code harder to maintain.. Maintenance and its related costs is an important (often overlooked) goal of good code design (ie.Software Engineeing). –  Apr 26 '12 at 20:12
0

You need a pointer to an instance of System. So to access the member variable:

System* system = GetSystem();
system->school_end[0] = whatever();

This is exactly the same as accessing a member via a struct pointer.

But saying that, it is good practice to hide access via methods:

- (int)getSchoolEndAtIndex:(int)index
{
    return school_end[index];
}
Cthutu
  • 8,713
  • 7
  • 33
  • 49
0

A common way to share data across classes in iOS apps is by following the singleton pattern.

SystemModel.h

#import <Foundation/Foundation.h>

@interface SystemModel : NSObject {
    @public
    float length_of_one_hour; 
    float length_of_first_break;
    float length_of_second_break;
    float length_of_lunch_break;
    float length_of_shortned_hour;
    float school_begin;

    int school_end[5];
    float school_length[5]; 
}
+(SystemModel*)instance;
@end

SystemModel.m

@implementation SystemModel
static SystemModel* _instance= nil;

+(SystemModel*)instance {
    @synchronized([SystemModel class]) {
        if (!_instance)
            [[self alloc] init];
        return _instance;
    }
    return nil;
}

+(id)alloc {
    @synchronized([SystemModel class]) {
        return (_instance = [super alloc]);
}
    return nil;
}

-(id)init {
    self = [super init];
    if (self != nil) {
        // your init code
    }
    return self;
}

@end

Now you can use your instance like this:

 float tmp = [SystemModel instance]->length_of_one_hour;

You could also convert instance variables to properties, and use the dot syntax. It does not matter for floats and arrays, but for id-based objects using properties is preferred.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks for your answer ... I'm still working on getting the instance to work in my About_now class and there is an error saying its protected – ferdyyy Apr 26 '12 at 20:33
  • @ferdyyy Oh yes, you're right! I copied your definition, but forgot to add `@public` to make it accessible. Please see the edit. – Sergey Kalinichenko Apr 26 '12 at 20:50
  • Thanks a lot. It works. Unfortunately it's night over here in Germany, so i need to go to sleep. I'm going to rewrite everything tomorrow. Thanks again – ferdyyy Apr 26 '12 at 21:29
0

You could expose the system instance variables via getters/setters (@property / @synthesize) and pass a reference to other classes instances.

@interface System : UIViewController{

float length_of_one_hour; //... @property (nonatomic,assign); .. @end

OtherClass other = [[OtherClass alloc] initWithSystem:sys]; or with a setter [other setSystem:sys];

hburde
  • 1,441
  • 11
  • 6