【问题标题】:declaring global variables in iPhone project在 iPhone 项目中声明全局变量
【发布时间】:2010-11-17 23:02:56
【问题描述】:

如何声明一个全局 NSArray,然后在我的应用程序中使用它?

【问题讨论】:

    标签: objective-c iphone iphone-sdk-3.0


    【解决方案1】:

    有几种可能性。最受欢迎:

    1 使用单例对象 - http://www.galloway.me.uk/tutorials/singleton-classes/

    2 在应用委托中声明:

    @interface Your_App_Delegate : UIResponder <UIApplicationDelegate>
    
    @property (nonatomic, strong) NSArray *array;
       . . .
    

    并访问它:

    ((Your_App_Delegate*)[[UIApplication sharedApplication] delegate]).array;
    

    3 使用NSUserDefault

    【讨论】:

      【解决方案2】:

      这里的每个人似乎都有一个隐含的、省略的第一行:“你可以做到 K&R C 风格,或者......”

      是的,你仍然可以使用 C 风格。

      在文件 1 中:

      NSArray *MyArray;
      

      在文件 2 中:

      extern NSArray *MyArray;
      

      在这里扮演明显的船长。

      【讨论】:

      • 这不是很明显,我认为没有 C 经验的新 Obj-C 开发人员是相当普遍的。
      【解决方案3】:

      有几种不同的方法可以做到这一点:

      1. 与其将其声明为全局变量,不如将其包装在一个单例对象中,然后让单例在任何地方都可用(通过#importing .h 文件)

      2. 创建一个 .h 文件,例如“Globals.h”。在 .h 中,将数组声明为 extern NSMutableArray * myGlobalArray; 然后在应用程序的其他位置(AppDelegate 是一个好地方),只需执行:myGlobalArray = [[NSMutableArray alloc] init]; 然后在任何需要数组的地方,只需 #import "Globals.h"

      3. 这类似于 #2,但没有全局标题。您可以在项目的 .pch 文件的 #ifdef __OBJC__ 块内将数组定义为 extern NSMutableArray *myGlobalArray;。 .pch 文件是一个头文件,它会自动#imported 到项目中的每个文件中。

      每种方法各有利弊。我在不同的情况下在不同的时间使用了这三种。我会说单例方法可能是最合适的,因为它对于初始化、访问限制和内存管理将是最灵活的。但是,如果您不需要,它可能是不必要的。

      如果您不想将大量“全局”变量暴露给项目中的每个文件,那么选项 #2 会很好。你可以在需要的地方#import它。然而,这种方法(以及#3)将声明与初始化分离(即,对象不是在它声明的位置附近创建的)。有些人可能会认为这是不正确的,他们可能是正确的。

      选项#3 很好,因为这样你就不必记住#import 任何东西了。但是,它提出了与选项 #2 相同的问题。

      【讨论】:

      • 您好,我使用了第三个选项,但是当我使用 static extern NSMutableArray * myGlobalArray; 时,会出现 Multiple Storage classes in declaration specifier 的错误
      • @rptwsthi 是的,对不起。只需删除“静态”位即可。
      • 上次我未能从第三种方式获得所需的响应,但这次我做到了。谢谢你的这篇好文章。 :)
      • 我使用了第三种方法,我有 NSString *global;当我写 global = @"data"; 时,变量和在我的控制器中然后它给了我 Symbol(s) not found 错误。我做错了什么。
      • 如果我关闭我的应用程序,这个数组会包含记录吗??
      【解决方案4】:

      这里参考戴夫的回答:

      这类似于 #2,但没有全局标题。您可以将数组定义为 static extern NSMutableArray *myGlobalArray;在项目的 .pch 文件的 #ifdef OBJC 块内。 .pch 文件是一个头文件,它会自动 #imported 到项目中的每个文件中。

      typedef是存储类,static是存储类,只能在一个存储类中定义对象。取出“静态”将允许应用程序与您上面的答案一起编译。

      【讨论】:

        【解决方案5】:

        如果您正在考虑为您的应用存储某种共享首选项,请使用 [NSUserDefaults sharedDefaults] 保存可跨应用使用的简单数据。如果您要存储瞬态数据,那么“静态”方法将与其他地方一样工作。

        但是,最好使用带有类访问器(如 NSUserDefaults)的单例对象方法,然后提供实例访问器方法来获取您的数据。这样,您就可以将自己与未来潜在的数据结构更改隔离开来。然后,您将使用静态变量,如上所述,但在 .m 文件中(因此您不需要“外部”定义)。它通常看起来像:

        static Foo *myDefault = nil;
        @implementation Foo
        +(Foo)defaultFoo {
          if(!myDefault)
            myDefault = [[Foo alloc] init]; // effective memory leak
          return myDefault;
        }
        @end
        

        然后您将拥有实例访问器,并将它们用作 [[Foo defaultFoo] myArray] 可以从应用程序的任何部分访问,并且不会出现任何编译时错误。

        【讨论】:

          【解决方案6】:

          第四个答案是在UIApplicationDelegate 中声明数组并通过

          [[[UIApplication sharedApplication] delegate] myArray];
          

          当我只需要几个全局对象时,我发现这是最简单、最干净的方法。

          【讨论】:

          • +1 这也是一个好方法。唯一需要注意的是它会产生一个编译器警告,因为 -[UIApplication delegate] 返回一个 id 类型的对象,它没有“myArray”方法。解决方案是强制转换它,但这会使这条线更难准备好:[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] myArray];
          • 另外,强制转换意味着您还需要#import MyAppDelegate 头文件。
          • 我使用 Xcode 4.3。您提到的情况将导致错误,而不仅仅是警告。
          • 由于此解决方案在访问时隐式使用 myArray 的 getter 方法,因此必须在 appDelegate.m(或 .h)中将数组声明为 @property 才能使其工作。完整的代码示例比没有注释的一行要好得多,至少对于新手而言。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多