[英]Don't understand global variables
我正在开发一个经常需要共享变量的iPad应用程序。 对我来说,似乎最简单的解决方案是用全局变量创建一个类,而不是着眼于来回传递-因为我对此也遇到了一些问题。
使用带有故事板的Xcode 5为iPad IOS7在Objective-C中创建和使用全局变量的最简单方法是什么?
(我知道有重复项,但我无法使它起作用)
编辑:在@nhgrif和其他评论之后,我在稍微更改我的答案
传递变量或使用全局变量的方式实际上取决于您尝试执行的操作。
以下是几种方法:
可以简单地将一个值从一个视图传递到另一个视图,然后再将其添加到堆栈中:
ViewController *viewController = [[ViewController alloc] init];
viewController.yourIntegerValue = 42;
[self presentViewController:viewController animated:YES completion:nil];
NSUserDefaults非常适合您希望传递或保存以供以后使用的通用小数据块。 参见AlwaysWannaLearn的示例,我通常为所有通用值(带有键)构建并存储NSDictionary。 (另请参阅我同意的@nhgrif的评论)
AppDelegate解决方案是@Martin Koles建议的另一种方法。 也许可以使用一组值,但如果只是为了将所有全局变量放在一个地方,我会避免使用它。
单例解决方案(原始答案)。 它简单,可扩展,优雅且高效。 我通常将其中之一添加到我创建的任何项目中。
这是快速进行操作的方法:
创建一个新文件:MyManager.h
#import <foundation/Foundation.h>
@interface MyManager : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
创建一个新文件: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
就是这样-该课程将掌握您的全球职能和价值观
要使用此技巧,请将以下行粘贴到项目中的其他任何位置
MyManager *sharedManager = [MyManager sharedManager];
//int getValuefromSingleton = sharedManager.MyFunctionOrValue;
实现和使用Singleton Pattern的最简单方法:
创建一个NSObject继承的类,您的头文件(.h)应如下所示:
@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
这将是您的实现(.m)类:
@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
您也可以在头文件中定义变量。
您可以在整个应用程序中使用设置/获取变量,如下所示:
[[MySingletonClass sharedInstance] setName:@"Test"];
NSString *name = [[MySingletonClass sharedInstance] name];
而不是使用全局变量,您应该使用NSUserDefaults
或Keychain
来存储键值对,并且可以在应用程序的任何位置和任何控制器中使用它们。 由于安全性较低,一般不建议使用全局变量。 它们的价值可以轻松更改。 与全局变量相比, Keychain
和NSUserDefaults
更安全,您可以在一个位置存储多个值。 使用NSUserDefaults
的示例如下,其中将值存储在其中并在应用程序中的任何位置使用。
对于存储键值对:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:[finalDetails valueForKey:@"Std_Id"] forKey:@"Std_Id"];
用于在其他控制器中获取该值。
NSString *stdId = [[NSUserDefaults standardUserDefaults] valueForKey:@"Std_Id"];
具有不保留状态的全局变量的最简单方法是在AppDelegate(您的应用中的Singleton)上具有属性:
在AppDelegate.h文件中:
@property (strong, nonatomic) NSString *globalString;
在任何需要访问的地方:
#import "AppDelegate.h"
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// use appDelegate.globalString ...
如果您需要在类中多次使用AppDelegate,则将其定义为property并延迟启动:
@property (nonatomic, strong) AppDelegate *appDelegate;
- (AppDelegate *)appDelegate
{
if (!_appDelegate) {
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
return _appDelegate;
}
但是,您应该始终避免这种情况违反OOP规则。 我建议您阅读iOS设计模式,尤其是MVC,Facade和Singleton: iOS设计模式
也可以使用Singleton NSUserDefaults
,但这是为了保留状态,因为它在应用终止后仍然有效。
我尝试仅将NSUserDefaults
用于相对简单的值,这些值需要在应用程序的执行之间保持NSUserDefaults
-对于更复杂的数据,Core Data可能更合适。
对于瞬态数据,我更喜欢使用数据模型类。
数据模型类将具有必需的属性,有时还具有一些用于处理数据的类或实例方法。 一旦将数据放入模型类中,通常就很容易在视图控制器之间传递引用,而无需使用“全局变量”。 如果确实需要“全局变量”,则可以使用单例模式 -例如,[UIApplication sharedApplication]是单例。
您可以使用以下结构创建单例
MyData.h
@interface MyData : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedMyData
@end
MyData.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;
}
然后,无论何时需要访问数据,都可以使用[MyData sharedMyData];
对其进行引用[MyData sharedMyData];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.