不了解全局变量

时间:2014-05-28 11:12:28

标签: ios objective-c ipad global-variables global

我正在为iPad开发一款经常需要共享变量的应用。对我而言,似乎最简单的解决方案是创建一个具有全局变量的类,而不是专注于来回传递 - 因为我也遇到了一些问题。

在使用Xcode 5和故事板的iPad IOS7的Objective-C中创建和使用全局变量的最简单方法是什么?

(我知道有重复但我无法使其发挥作用)

5 个答案:

答案 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)

使用全局变量,您应该使用存储键值对的NSUserDefaultsKeychain,并且可以在应用程序的任何位置和任何控制器中使用它们。由于安全性较低,通常不优选全局变量。他们的价值可以很容易地改变。与全局变量相比,KeychainNSUserDefaults更安全,您可以在一个位置存储多个值。使用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];

获取对数据的引用