Pass a variable between lots of UIVIewControllers
In my iPhone app, there is a setup assistant which helps users to 开发者_JAVA百科input a lot of data. It's basically a UINavigationController with lots of UIViewControllers in it. Now, at a certain point, I want to access a variable that the user entered in the first UIViewController he saw. I could pass the variable between every UIViewController with a setter method, but I guess there is an easier way.
You can declare global or class variables in C style if you want to. If you want the same variable to be available in several of your sub classes of UIViewController, you'd declare it as an extern variable in the .h file of your first controller, for example:
#import <UIKit/UIKit.h>
extern NSString *myGlobalString;
@interface MyFirstViewController : UIViewController {
...
You'd then redeclare it in your .m file without the extern.
#import "MyFirstViewController.h"
NSString *myGlobalString;
@implementation MyFirstViewController
You shouldn't redeclare it in the other .m or .h files, but you can access the variable in all files that import MyFirstViewController.h
. When setting the variable, take care to release and retain it properly. It's easy to create a memory leak with this kind of global variable.
A simple yet reusable and extensible way to solve this problem is using a singleton.
Declare a new class named SetupConfig, for example.
Your SetupConfig.h should then look as follows:
@interface SetupConfig : NSObject {
NSString *_myString;
}
@property (retain) NSString *myString;
+ (id)sharedSetupConfig;
@end
And the corresponding SetupConfig.m:
#import "SetupConfig.h"
SetupConfig *g_sharedSetupConfig = nil;
@implementation SetupConfig
@synthesize myString = _myString;
+ (id)sharedSetupConfig {
if (!g_sharedSetupConfig) {
g_sharedSetupConfig = [[SetupConfig alloc] init];
}
}
@end
Now, in the view controller implementation you want to access myString from:
@import "MyViewController.h"
@import "SetupConfig.h"
@implementation MyViewController
- (void)methodDoingSomethingWithSingletonString
{
NSString *myString = [[SetupConfig sharedSetupConfig] myString];
}
@end
The singleton approach comes with a number of advantages over using a global C variable. First of all you do not have to re-declare your global variables over and over. What is more, your "global" variables are encapsulated in a class. Synthesizing property getters/setters is a nice way to abstract the actual variable away from the rest of your code. Finally, this implementation may be integrated into unit tests easily.
Ya , there is much a easy way to handle this.....
You can take a Global Variable
In your Delegate.h file declare your variable:
@interface Smoke_ApplicationAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
NSString *messageString; //This would be your String Variable
}
@property(nonatomic,retain)NSString *messageString;
Secondly in Delegate.m file
@implementation Smoke_ApplicationAppDelegate
@synthesize window;
@synthesize navigationController;
@synthesize messageString; // Synthesize it over here..
This is Done .Now you can use this String Variable in All/any class you want..
To use this Global Variable.
Just import you Delegate file make the obj of it....
#import "DelegateFile.h"
@implementation About
DelegateFile *appDel;
Now in Your class.m
- (void)viewDidLoad {
[super viewDidLoad];
appDel=[[UIApplication sharedApplication]delegate];
}
Now you can access it anywhere in your class by this Object:
appDel.messageString
Just follow my Steps Carefully After giving so much pain to my finger, I am sure this is definitely going to help you.....
Have a easy life,
You can use a singleton instance, available from all your classes, that will handles all the information you need.
Singleton in objective-C, Wikipedia
I wouldn't be too quick to circumvent the data encapsulation that is such a good feature of Objective-C.
If you are collecting something you would consider to be "Settings" consider using NSUserDefaults.
If your views proceed in a structured one to the next to the next way, consider making a "data" class, whatever it is you're making, then pass it along from parent view to subview until you get there. (Remember that "passing" is not an expensive operation, the stuff stays put, you're passing a little pointer)
If you really want the singleton route, consider making it a property of the application delegate (an already existing singleton)
Remember that only the route of "passing in" the data gives the added advantage that later, maybe you will want to collect that starting information multiple times, and launch different possible last-views, and it's trivial to just pass in a different one. If you go the global route you'll then have to start re-writing everywhere you accessed it before.
You can use it as a singleton or you can keep it in the app delegate and call like [appdelegate getstring];
精彩评论