Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Don';我不理解全局变量_Ios_Objective C_Ipad_Global Variables_Global - Fatal编程技术网

Ios Don';我不理解全局变量

Ios Don';我不理解全局变量,ios,objective-c,ipad,global-variables,global,Ios,Objective C,Ipad,Global Variables,Global,我正在为iPad开发一款应用程序,它经常需要共享变量。对我来说,似乎最简单的解决方案是创建一个带有全局变量的类,而不是专注于来回传递,因为我在这方面也遇到了一些问题 在objective-C for iPadIOS7中,使用带有故事板的Xcode 5创建和使用全局变量的最简单方法是什么 (我知道存在重复项,但我无法使其工作)与其使用全局变量,不如使用存储键值对的NSUserDefaults或Keychain,您可以在应用程序的任何位置和任何控制器中使用它们。由于安全性较差,通常不首选全局变量。它

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

在objective-C for iPadIOS7中,使用带有故事板的Xcode 5创建和使用全局变量的最简单方法是什么


(我知道存在重复项,但我无法使其工作)

与其使用全局变量,不如使用存储键值对的
NSUserDefaults
Keychain
,您可以在应用程序的任何位置和任何控制器中使用它们。由于安全性较差,通常不首选全局变量。它们的价值很容易改变<与全局变量相比,code>Keychain和
NSUserDefaults
更安全,您可以在一个位置存储多个值。使用
NSUserDefaults
的示例如下,其中值存储在其中并在应用程序中的任何位置使用

用于存储键值对:

 NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
 [prefs setObject:[finalDetails valueForKey:@"Std_Id"] forKey:@"Std_Id"];
用于在其他控制器中获取该值

NSString *stdId = [[NSUserDefaults standardUserDefaults] valueForKey:@"Std_Id"];
编辑:在@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 *sharedManager = [MyManager sharedManager];
//int getValuefromSingleton = sharedManager.MyFunctionOrValue;

实现和使用Singleton模式的最简单方法:

创建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
[[MySingletonClass sharedInstance] setName:@"Test"];
NSString *name = [[MySingletonClass sharedInstance] name];
这将是您的实现(.m)类:

您还可以在头文件中定义变量

您可以在整个应用程序中使用设置/获取变量,如下所示:

@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
[[MySingletonClass sharedInstance] setName:@"Test"];
NSString *name = [[MySingletonClass sharedInstance] name];

拥有不保留状态的全局变量的最简单方法是在AppDelegate(应用程序中的单例)上拥有一个属性:

在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:


Singleton
NSUserDefaults
也可以使用,但这是为了在应用程序终止后保留状态。

我尝试只使用
NSUserDefaults
用于在应用程序执行之间需要保留的相对简单的值-对于更复杂的数据,核心数据可能更合适

对于瞬态数据,我更喜欢使用数据模型类

数据模型类将具有必需的属性,有时还具有一些类或实例方法来操作数据。在模型类中拥有数据后,在视图控制器之间传递引用通常非常简单,并且不需要“全局”。如果您确实需要“globals”,那么您可以使用一个-例如,[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]获取对数据的引用

了解单例模式并使用它们。使用全局模式几乎从来都不是一个好主意。如果你需要它们,请理解并使用singleton模式,als Salman说,我认为你想为你的整个程序创建一个全局类。这是一种很好的封装、保护数据的方法,也是一种有组织的方式来做你想做的事情。仅仅因为2或3个类需要访问一个变量并不意味着200-300个类需要访问该变量。如果你给出一些更具体的例子,说明何时/何地/如何共享变量,这个问题会更好一些,因为几乎总是有比全局共享更好的方法。我非常失望,因为事实上,前三条评论都是立即推荐单例,而不是催促获取更多信息。看起来用户很可能只需要在几个视图控制器之间传递数据,而这不太可能是一种真正合法地保证任何类型的全局变量的情况……我已经在我的应用程序中使用了很多NSUserDefaults,但我认为这是一种奇怪的方式——一直在保存一些东西。你确定这是个好办法吗?它会一直保存和读取。苹果会批准吗?我想不出任何理由拒绝使用
NSUserDefaults
。这是一种存储经常使用的信息的好方法。我也用过,很好。是的,如果您想要更多的安全性,您可以选择使用
钥匙链
。就
NSUserDefaults
而言,您可以放心地使用它:钥匙链应用于登录信息等,但不用于在ViewController之间传递信息。每个用户看到他们的钥匙链乱七八糟都会义愤填膺