【问题标题】:Where do I create global variables for an iOS app?在哪里为 iOS 应用程序创建全局变量?
【发布时间】:2012-03-06 23:30:09
【问题描述】:

这是我的代码:

我希望能够创建一个全局 NSMutableArray,它可以存储 Budget* 对象,然后可以将其写入 .pList 文件...我只是在学习 pList 是什么,我对如何实现它们...

我哪里错了?

- (IBAction)btnCreateBudget:(id)sender 
{
    Budget *budget = [[Budget alloc] init];

    budget.name = self.txtFldBudgetName.text;
    budget.amount = [self.txtFldBudgetAmount.text intValue];    

    // Write the data to the pList
    NSMutableArray *anArray = [[NSMutableArray alloc] init]; // I want this to be a global variable for the entire app. Where do I put this?

    [anArray addObject:budget];

    [anArray writeToFile:[self dataFilePath] atomically:YES];

    /* As you can see, below is where I test the code. Unfortunately, 
    every time I run this, I get only 1 element in the array. I'm assuming 
    that this is because everytime the button is pressed, I create a brand new 
    NSMutableArray *anArray. I want that to be global for the entire app. */

    int i = 0;
    for (Budget * b in anArray)
    {
        i++;
    }
    NSLog(@"There are %d items in anArray",i);

}

-(NSString *) dataFilePath
{ 
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentDirectory = [path objectAtIndex:0]; 
    return [documentDirectory stringByAppendingPathComponent:@"BudgetData.plist"];
}

edit:我想补充一点,我正在创建 anArray 数组,以便其他视图可以访问它。我知道这可以通过 NSNotification 来完成?还是我应该这样做 appDelegate 类?最终目标是让 anArray 对象填充位于单独视图中的 UITableView。

【问题讨论】:

  • 为什么要它是全局的而不是实例变量?
  • 不是我反对 plist 而是您是否考虑过其他存储格式,例如 JSON(使用 JSONKit)?如果您打算为其他设备(android)编写此应用程序,JSON 可能是更好的选择。
  • 为什么你希望数组在范围内是全局的?还有哪些对象需要访问它?
  • 我这样做主要是为了练习应用程序中的持久性概念。但是谢谢@Prowla
  • 好吧,我希望能够使用从当前视图创建的对象填充 UITableView。 @skinnyTOD

标签: objective-c ios global-variables


【解决方案1】:

把声明放在方法外面而不是里面。

NSMutableArray *anArray = nil;

- (IBAction)btnCreateBudget:(id)sender 
{
    ...
    if ( anArray == nil )
      anArray = [[NSMutableArray alloc] init]; 
    ...
}

如果仅在一个文件中使用,请将其设为“静态”以防止与其他文件发生名称冲突:

    static NSMutableArray *anArray = nil;

如果只在一种方法中使用,请将其设为“静态”并将其放入该方法中:

- (IBAction)btnCreateBudget:(id)sender 
{
    static NSMutableArray *anArray = nil;
    ...
    if ( anArray == nil )
      anArray = [[NSMutableArray alloc] init]; 
    ...
}

请注意,人们通常对全局变量使用某种命名约定,例如“gArray”,以便轻松地将它们与局部变量、实例变量或方法参数区分开来。

【讨论】:

  • 如果 OP 计划对这段代码进行多线程处理,则可能值得将初始化包装在 dispatch_once() 构造中。
【解决方案2】:

在这种情况下不需要全局变量。你可以这样做:

  1. 将旧数据读取到可变数组 (initWithContentsOfFile:)。
  2. 向数组中添加新记录。
  3. 将数组保存到同一文件中。

但您代码中的第二个问题是,如果您的 Budget 类不是属性列表类型(NSString、NSData、NSArray 或 NSDictionary 对象)writeToFile: 将无法成功保存。

【讨论】:

【解决方案3】:

您需要确保您的 Budget 类调用 NSCoder,然后调用 NSCoder initWithCoder:NSCoder decodeWithCoder: 方法。否则,writeToFile: 将不适用于您的 NSObject 类。

但我离题了。原问题的答案应该如下。

在您的.h 文件中,您需要执行以下操作。

@interface WhateverClassName : UIViewController 
{
    NSMutableArray *anArray;

}

@property(nonatomic, retain) NSMutableArray *anArray;
@end

然后,您需要确保您@synthesizeNSMutableArray,这样您就不会收到任何奇怪的警告。这是在您的 .m 文件中的 @implementation 行之后完成的。

然后,在您希望将其分配到内存的函数中,只需执行以下操作。

anArray = [[NSMutableArray alloc] initWithObjects:nil];

现在这是一个global 变量。它是global,它可以在任何函数中使用,并且不限于在一个函数中使用。

【讨论】:

  • 全局如何,因为它可以被应用程序中的任何视图访问?
  • 属性不是真正的“全局”。它们仅在类范围内是全局的。他想让“整个应用程序全球化”
  • 我很欣赏这个答案。这也很有帮助@Sebastian Peek
  • 当然,应用程序中的任何视图都可以访问它,但这绝对是创建property@property的最简单方法,该property可以在类中的任何位置访问。
【解决方案4】:

如果您希望数据可供整个应用程序或上下文(“全局”)访问,您可以使用单例。但是,请谨慎执行此操作,并确保它确实是必要且适当的。我建议在任何单例实现之前做大量的阅读。 Carter Allen 有一个很好的基本实现here

根据“最终目标是让 anArray 对象填充位于单独视图中的 UITableView”,您无需向文件、数据库或单例写入任何内容。只需设置对象。正如 Sebastien Peek 所说。

如果您希望离线数据存储,请查看 sqlite、json、plist 等

【讨论】:

  • OP 不希望 Budget 成为“全局”属性,他希望 NSMutableArray 成为。此答案与 OP 无关。
  • 当然,但是对于 OP 试图实现的目标,这不是必需的。
  • 我没有说明在这些(模糊的)情况下需要单例。 OP 提到他主要是作为一种坚持不懈的练习来做这件事,因此,我假设要学习。所以我想我会提出单例的概念,看到标题是:“我在哪里为 iOS 应用程序创建全局变量?”还有一个单身人士还没有提到。
猜你喜欢
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 2013-02-10
  • 1970-01-01
  • 2011-02-09
相关资源
最近更新 更多