No entiendo las variables globales
Frecuentes
Visto 242 equipos
0
I'm developing an app for iPad that often needs to share variables. Too me it seems like the easiest solution would be to create a class with global variables instead of focusing on passing back and forth - as I've also had some problems with that.
What's the easiest way to create and use global variables in objective-C for iPad IOS7 using Xcode 5 with storyboards?
(I know there are duplicates but I can't make it work)
5 Respuestas
1
Edit: following @nhgrif and others comments, I am slightly changing my answer
The way to pass variables or use global variables really depends on what you try to do.
Here are few ways:
Passing a value from one view to the other can simply be done before adding it to the stack as so:
ViewController *viewController = [[ViewController alloc] init];
viewController.yourIntegerValue = 42;
[self presentViewController:viewController animated:YES completion:nil];
NSUserDefaults are great for generic small chunks of data which you like to pass around or save for later use. see example from AlwaysWannaLearn, I usually build and store NSDictionary for all the generic value (with keys). (also see comment from @nhgrif which I agree with)
AppDelegate solution is another way to go as @Martin Koles suggested. Perhaps ok for a single set of value, I would avoid it if just for the sake of having all my globals in one place.
Semifallo solution (original answer). it is simple, expandable, elegant and efficient. I usually add one of them to any project I create.
here is how to do it quickly:
create a new file : MyManager.h
#import <foundation/Foundation.h>
@interface MyManager : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
create a new file : MyManager.m
#import "MyManager.h"
@implementation MyManager
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
}
@end
Thats it really - this class will hold your global functions and values
To use this nifty trick , paste the following line anywhere else in your project
MyManager *sharedManager = [MyManager sharedManager];
//int getValuefromSingleton = sharedManager.MyFunctionOrValue;
contestado el 29 de mayo de 14 a las 08:05
1
Easiest and Simplest way of implementing and using Singleton Pattern:
Create a NSObject inherited class, your header file (.h) should be like this:
@interface MySingletonClass : NSObject
//this method will be used to get singleton instance
+ (MySingletonClass *)sharedInstance;
//some variables getters and setters
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setAge:(int)age;
- (int)age;
@end
This would be your implementation (.m) class:
@interface MySingletonClass() {
}
//your global variables
@property (nonatomic, strong) NSString *name;
@property (nonatomic) int age;
@end
@implementation MySingletonClass
static MySingletonClass *sharedInstance = nil;
//this method will be used to get singleton instance
+ (MySingletonClass *)sharedInstance {
if(sharedInstance == nil){
sharedInstance = [[MySingletonClass alloc] init];
}
return sharedInstance;
}
-(id)init {
if(self = [super init]) {
_name = @"";
_age = 0;
}
return self;
}
//some variables getters and setters
- (void)setName:(NSString *)name {
_name = name;
}
- (NSString *)name {
return name;
}
- (void)setAge:(int)age {
_age = age;
}
- (int)age {
return age;
}
@end
you can also define your variables in header file too.
You can use set/get your variables throughout the application like this:
[[MySingletonClass sharedInstance] setName:@"Test"];
NSString *name = [[MySingletonClass sharedInstance] name];
contestado el 28 de mayo de 14 a las 12:05
0
Rather using global variables, you should use NSUserDefaults
or Keychain
which store key-value pairs and you can use them anywhere and in any controller of your application. Global variables are generally not preferred due to less security. Their value can be changed easily. Keychain
y NSUserDefaults
are more secure compared to global variables and you can store multiple values in a single place. A sample for using NSUserDefaults
is as follows where value is stored in it and used anywhere in the application.
For Storing key-value pair :
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:[finalDetails valueForKey:@"Std_Id"] forKey:@"Std_Id"];
For fetching that value in some other controller.
NSString *stdId = [[NSUserDefaults standardUserDefaults] valueForKey:@"Std_Id"];
contestado el 28 de mayo de 14 a las 12:05
I've used NSUserDefaults a lot in my app already, but I thought of it as a weird way - saving something all the time. Are you sure this is a good way? It'll save and read ALL the time. Will Apple approve it? - user3680475
I can't think of any reason to reject using NSUserDefaults
. Its a decent way to store regularly used information. I've also used and its fine. And yes, if you want more security, you can opt to use Keychain
. Hasta NSUserDefaults
is concerned, you can be at ease while using it. :) - drumil
The keychain should be used for login information ans so on but not for passing information between viewControllers. Every user would be outraged to see that their keychain is littered with some useless information of an app. NSUserDefaults is for storing small values, like preferences, permanently and also shouldn't be used for this. - Kai Engelhardt
0
I try to only use NSUserDefaults
for relatively simple values that need to persist between executions of an app - for more complex data Core Data is probably more appropriate.
For transient data, I prefer to use a data model class.
The data model class will have the required properties and sometimes some class or instance methods to manipulate the data. Once you have your data in a model class it is normally pretty simple to pass the reference between your view controllers and avoid the need for 'globals'. If you really do need 'globals' then you can use a patrón singleton - for example, [UIApplication sharedApplication] is a singleton.
You can create a singleton using the following structure
MisDatos.h
@interface MyData : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedMyData
@end
MisDatos.m
#import "MyData.h"
@implementation MyData
#pragma mark Singleton Methods
+ (id)sharedMyData {
static MyData *sharedMyData = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyData = [[self alloc] init];
});
return sharedMyData;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
Then, wherever you need to access your data you can get a reference to it using [MyData sharedMyData];
contestado el 28 de mayo de 14 a las 12:05
0
The easiest way to have a global wide variable that does not preserve state is to have a property on an AppDelegate (which is a Singleton in your app):
In AppDelegate.h file:
@property (strong, nonatomic) NSString *globalString;
And everywhere you need access:
#import "AppDelegate.h"
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// use appDelegate.globalString ...
and if you need to use AppDelegate more then once in your class, then define it as property and lazily initiate:
@property (nonatomic, strong) AppDelegate *appDelegate;
- (AppDelegate *)appDelegate
{
if (!_appDelegate) {
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
return _appDelegate;
}
However, you should always try to avoid that as it goes against OOP rules. I suggest you read iOS Design Patterns especially MVC, Facade and Singleton: iOS Design Patterns
Semifallo NSUserDefaults
can be used as well, but this is rather for preserving state as it survives app termination.
contestado el 28 de mayo de 14 a las 12:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas ios objective-c ipad global-variables global or haz tu propia pregunta.
Learn about Singleton Patterns and use them.. - Salman Zaidi
Going for globals is almost never a good idea. If you need them, understand and use the singleton pattern, als Salman says. - Daniel Schneller
I think you want to create a global class for your whole program. It's a nice way to encapsulate, protect the data, and the organized way to do what you want. - int3
Just because 2 or 3 classes need access to a variable doesn't mean 200-300 classes need access to that variable. This question would be a bit better if you gave some more concrete examples of when/where/how you need to share variables, because there's almost always a better way than globals. - nhgrif
I'm quite disappointed in SO in fact that the first three comments are all instantly recommending singletons rather than prodding for more information. It seems most likely that the user probably only needs to pass data between a few view controllers and unlikely that this is truly a situation that legitimately warrants global variables of any sort... - nhgrif