我正在为iPad开发一款经常需要共享变量的应用。对我而言,似乎最简单的解决方案是创建一个具有全局变量的类,而不是专注于来回传递 - 因为我也遇到了一些问题。
在使用Xcode 5和故事板的iPad IOS7的Objective-C中创建和使用全局变量的最简单方法是什么?
(我知道有重复但我无法使其发挥作用)
答案 0 :(得分:1)
编辑:关注@nhgrif和其他人的评论,我稍微改变了我的回答
传递变量或使用全局变量的方法实际上取决于你尝试做什么。
以下几种方法:
将值从一个视图传递到另一个视图可以在将其添加到堆栈之前完成,如下所示:
ViewController *viewController = [[ViewController alloc] init];
viewController.yourIntegerValue = 42;
[self presentViewController:viewController animated:YES completion:nil];
NSUserDefaults 非常适合您希望传递或保存以供日后使用的一般小块数据。从AlwaysWannaLearn看到示例,我通常为所有通用值(使用键)构建和存储NSDictionary。 (另请参阅我同意的@nhgrif的评论)
@ partin Koles建议,AppDelegate 解决方案是另一种方式。对于一组值可能没问题,如果只是为了将所有全局变量放在一个地方,我会避免使用它。
Singleton 解决方案(原始答案)。 它简单,可扩展,优雅和高效。我通常会将其中一个添加到我创建的任何项目中。
以下是如何快速完成的工作:
创建一个新文件: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;
答案 1 :(得分:1)
实现和使用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
您也可以在头文件中定义变量。
您可以在整个应用程序中使用set / get变量,如下所示:
[[MySingletonClass sharedInstance] setName:@"Test"];
NSString *name = [[MySingletonClass sharedInstance] name];
答案 2 :(得分:0)
使用全局变量,您应该使用存储键值对的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"];
答案 3 :(得分:0)
拥有一个不保留状态的全局变量的最简单方法是在AppDelegate上设置一个属性(在你的应用中是一个Singleton):
在AppDelegate.h文件中:
@property (strong, nonatomic) NSString *globalString;
您需要访问的任何地方:
#import "AppDelegate.h"
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// use appDelegate.globalString ...
如果您需要在课堂上再使用一次AppDelegate,那么将其定义为属性并懒惰地启动:
@property (nonatomic, strong) AppDelegate *appDelegate;
- (AppDelegate *)appDelegate
{
if (!_appDelegate) {
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
return _appDelegate;
}
但是,您应该始终尽量避免这种情况,因为它违反了OOP规则。我建议你阅读iOS设计模式,特别是MVC,Facade和Singleton:iOS Design Patterns
单例NSUserDefaults
也可以使用,但这可以保留状态,因为它可以在应用程序终止后继续存在。
答案 4 :(得分:0)
我尝试仅将NSUserDefaults
用于需要在应用程序执行之间保留的相对简单的值 - 对于更复杂的数据,Core Data可能更合适。
对于瞬态数据,我更喜欢使用数据模型类。
数据模型类将具有所需的属性,有时还有一些类或实例方法来操作数据。将数据放入模型类后,通常很容易在视图控制器之间传递引用,并且不需要“全局”。如果你确实需要'全局',那么你可以使用singleton pattern - 例如,[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];