【发布时间】:2010-11-17 23:02:56
【问题描述】:
如何声明一个全局 NSArray,然后在我的应用程序中使用它?
【问题讨论】:
标签: objective-c iphone iphone-sdk-3.0
如何声明一个全局 NSArray,然后在我的应用程序中使用它?
【问题讨论】:
标签: objective-c iphone iphone-sdk-3.0
有几种可能性。最受欢迎:
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
【讨论】:
这里的每个人似乎都有一个隐含的、省略的第一行:“你可以做到 K&R C 风格,或者......”
是的,你仍然可以使用 C 风格。
在文件 1 中:
NSArray *MyArray;
在文件 2 中:
extern NSArray *MyArray;
在这里扮演明显的船长。
【讨论】:
有几种不同的方法可以做到这一点:
与其将其声明为全局变量,不如将其包装在一个单例对象中,然后让单例在任何地方都可用(通过#importing .h 文件)
创建一个 .h 文件,例如“Globals.h”。在 .h 中,将数组声明为 extern NSMutableArray * myGlobalArray; 然后在应用程序的其他位置(AppDelegate 是一个好地方),只需执行:myGlobalArray = [[NSMutableArray alloc] init]; 然后在任何需要数组的地方,只需 #import "Globals.h"
这类似于 #2,但没有全局标题。您可以在项目的 .pch 文件的 #ifdef __OBJC__ 块内将数组定义为 extern NSMutableArray *myGlobalArray;。 .pch 文件是一个头文件,它会自动#imported 到项目中的每个文件中。
每种方法各有利弊。我在不同的情况下在不同的时间使用了这三种。我会说单例方法可能是最合适的,因为它对于初始化、访问限制和内存管理将是最灵活的。但是,如果您不需要,它可能是不必要的。
如果您不想将大量“全局”变量暴露给项目中的每个文件,那么选项 #2 会很好。你可以在需要的地方#import它。然而,这种方法(以及#3)将声明与初始化分离(即,对象不是在它声明的位置附近创建的)。有些人可能会认为这是不正确的,他们可能是正确的。
选项#3 很好,因为这样你就不必记住#import 任何东西了。但是,它提出了与选项 #2 相同的问题。
【讨论】:
这里参考戴夫的回答:
这类似于 #2,但没有全局标题。您可以将数组定义为 static extern NSMutableArray *myGlobalArray;在项目的 .pch 文件的 #ifdef OBJC 块内。 .pch 文件是一个头文件,它会自动 #imported 到项目中的每个文件中。
typedef是存储类,static是存储类,只能在一个存储类中定义对象。取出“静态”将允许应用程序与您上面的答案一起编译。
【讨论】:
如果您正在考虑为您的应用存储某种共享首选项,请使用 [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] 可以从应用程序的任何部分访问,并且不会出现任何编译时错误。
【讨论】:
第四个答案是在UIApplicationDelegate 中声明数组并通过
[[[UIApplication sharedApplication] delegate] myArray];
当我只需要几个全局对象时,我发现这是最简单、最干净的方法。
【讨论】:
[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] myArray];