繁体   English   中英

不了解全局变量

[英]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];

而不是使用全局变量,您应该使用NSUserDefaultsKeychain来存储键值对,并且可以在应用程序的任何位置和任何控制器中使用它们。 由于安全性较低,一般不建议使用全局变量。 它们的价值可以轻松更改。 与全局变量相比, KeychainNSUserDefaults更安全,您可以在一个位置存储多个值。 使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM