Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

CosmicChild87

macrumors newbie
Original poster
Nov 4, 2010
13
0
England
Hi all, Ive read everything about global variables, and understand the problems but i only need one variable to be accessable by more than one view, so a global variable seems the easiest way, however i having some trouble

globals.h
Code:
#import <Foundation/Foundation.h>

extern NSNumber *gcurrentGameID;

@interface globals : NSObject {

}

@end

globals.m
Code:
#import "globals.h"


@implementation globals

NSNumber *gcurrentGameID;
@end

app deleagate
Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
    // Override point for customization after app launch. 
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];
	
	NSNumber *gcurrentGameID = [NSNumber numberWithInt:0];


	return YES;
}

i then try to set it in one view using
Code:
gcurrentGameID = [NSNumber numberWithInt:(currentRow)];

and then try to access it in a further view

Code:
NSLog("The int value was %d",[gcurrentGameID intValue]);

this however gives a bad access error and the applications crashes - i have included my globals file in all the relevant files, and it seems to set ok, and can be viewed in the view it is set in but will not work elses where

any help is greatly appreciated

Alan
 
1) In AppDelegate.m:

Code:
NSNumber *gcurrentGameID = [NSNumber numberWithInt:0];

declares a new (different) gcurrentGameID with local scope which masks any global declaration of gcurrentGameID. You should have used:

Code:
gcurrentGameID = [NSNumber numberWithInt:0];


2) In globals.m, the declaration

Code:
NSNumber *gcurrentGameID;

is protected as it occurs within the @implementation ... @end block. You need to, at the very least, move it outside the block. This might work. If not, you could use plain ANSI-C instead:

In globals.h:

Code:
extern int gcurrentGameID;

In globals.m

Code:
int gcurrentGameID;

In AppDelegate.m:

Code:
#import globals.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after app launch. 
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    gcurrentGameID = 0;


    return YES;
}

Keep in mind that the global declaration "int gcurrentGameID;" should only occur in one place in your code; in this example this occurs in AppDelegate.m (which imports globals.m which contains the line "int gcurrentGameID;"). Your View.h should use "extern int gcurrentGameID;" (or import globals.h).

To avoid using globals, you could declare/define "NSNumber *currentGameID;" in your MyAppDelegate.h and MyAppDelegate.m as a property, using @property and @synthesize. Then, any view that needs access to gcurrentGameID could just ask your AppDelegate for it using

Code:
#import "MyAppDelegate.h"

...

[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] setCurrentGameID:[NSNumber numberWithInt:42]];

int localGameID = [[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] currentGameID] intValue];

The construct

Code:
(MyAppDelegate *)[[UIApplication sharedApplication] delegate]

is a useful idiom for getting the delegate of your app's (singleton) sharedApplication and then casting it into the form of your particular AppDelegate.


HTH
 
Last edited:
Also, in globals.m, you might want to have:

Code:
NSNumber *gcurrentGameID = nil;

to make sure the object pointer is initialized to something. And you also need to make sure any convenience objects are retained:

Code:
gcurrentGameID = [ [ NSNumber numberWithInt: 0 ] retain ];

and released if you re-assign the global (e.g. do manual memory management).
 
Thanks, ive got it sorted now using int as you suggested, thanks

also just an asside - id forgotten my @ at the start of the NSLog
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.