【问题标题】:Establishing a global array of strings [duplicate]建立一个全局字符串数组[重复]
【发布时间】:2014-01-21 15:50:18
【问题描述】:

在我的应用程序中,我从许多不同的视图控制器中引用了许多相同的字符串变量,并使用这种方法创建了许多全局 NSStrings:

OpeningController.h(在@interface 之前)

extern NSString *stringName;

OpeningController.m(在@interface { } @end 之后)

NSString *stringName =@"On";

然后我可以在我的应用程序的任何地方引用/更改 stringName

我希望能够对字符串数组执行相同的操作,但是当我尝试以下操作时,我收到错误 Initializer is not a compile-time constant

如何实现我想要实现的目标?

OpeningController.h

extern NSArray *arrayName;

OpeningController.m(在@interface { } @end 之后)

NSArray *arrayName = [NSArray arrayWithObjects:
                     @"String1",
                     @"String2",
                     @"String3",
                     @"String4",
                     nil];

【问题讨论】:

  • 标题对我来说难以辨认;)但马丁是对的

标签: ios nsarray


【解决方案1】:

假设openingController 是一个类名(提示:它应该是OpeningController)然后你可以在类的+initialize 方法中初始化数组,该方法将在运行时引用该类时立即调用:

OpeningController.m:

#import "OpeningController.h"

NSArray *arrayName = nil;

@implementation OpeningController

+ (void)initialize {
    arrayName = [NSArray arrayWithObjects:
                @"String1",
                @"String2",
                @"String3",
                @"String4",
                nil];
}

....

@end

编辑:请注意,这不是一个特别好的示例,因为引用数组而不首先引用OpeningController 将访问未初始化的数组。更好的方法是单例模式:

OpeningController.h:

@interface OpeningController : UIViewController  // Not sure of the subclass

+ (NSArray *)array;

...

@end

OpeningController.m:

#import "OpeningController.h"

@implementation OpeningController

+ (NSArray *)array {
    static NSArray *array = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        array = [NSArray arrayWithObjects:
                @"String1",
                @"String2",
                @"String3",
                @"String4",
                nil];
    });
    return array;
}

...

@end

【讨论】:

  • 感谢您的帮助。我已经尝试过了,但是当我这样做时 NSLog(@"Array text - %@", [arrayName objectAtIndex:0]);来自与 OpeningController 不同的控制器,它说该数组是未声明的标识符。
  • @RichardGriffiths 是的,+initialize 在代码中引用 OpeningController 之前不会触发。听起来您可能想要使用单例模式,所以您可以使用NSArray *array = [ObjectController array];。见这篇文章:galloway.me.uk/tutorials/singleton-classes
  • @RichardGriffiths 我已经用一个单例示例更新了我的答案。
  • 感谢您的光临。我真的很难通过 + (NSArray)array;在 {} 或“预期的 ';' 之外导致错误“接口类型 'NSArray' 不能按值返回”的行在声明列表的末尾”,在 {} 内。
  • @RichardGriffiths Arrrrg!那是因为它应该是NSArray *!立即修复。
【解决方案2】:

不要使用共享全局变量。它们在您的不同类之间创建了非常强的耦合,并迫使各种相互依赖。这很快就会导致意大利面条代码。

相反,创建一个数据容器单例。那是一个单例对象(在 Objective C 中的单例设计模式上进行谷歌搜索,甚至在此处搜索),其中包含您想要共享的属性。

然后,任何时候您想读取或写入全局变量,您都可以使用单例的访问器方法来获取单例,然后调用所需的属性。

NSUserDefaults 是 Apple 框架中的单例示例。代码

[NSUserDefaults sharedUserDefaults] 是一个类方法调用,它返回一个指向用户默认单例的指针。

您的代码可能类似于[MyDataSingleton sharedDataSingleton]

【讨论】:

  • 感谢 Duncan - 我一直在阅读 Matt Galloway 关于单身人士的文章底部的辩论,似乎对该方法存在一些疑问。我对此完全陌生,所以一无所知,但想知道这样做是否有任何问题。
【解决方案3】:

你必须初始化数组,否则它将不起作用。

您可以创建该类的一个实例并在每次需要时获取该实例。

如果您有任何问题,请告诉我:)

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多