代码之家  ›  专栏  ›  技术社区  ›  nevan king

如何使用NSArray作为全局常量?

  •  11
  • nevan king  · 技术社区  · 15 年前

    Constant.m

    // Constants.h
    extern NSString * const kDatabaseFileName;
    //Constants.m
    NSString * const kDatabaseFileName = @"target_one.sqlite";
    

    我还想为我的每个目标定义一个NSArray:

    NSArray * const kLabelNames = [[NSArray alloc] initWithObjects:
        @"nameLabel", @"addressLabel", nil];
    

    但这会给出“错误:初始值设定项元素不是常量”。使用“arrayWithObjects”也不起作用。这是因为数组中的字符串不是常量吗?

    如何将数组设置为全局常量?谢谢。

    6 回复  |  直到 15 年前
        1
  •  6
  •   Kendall Helmstetter Gelner    15 年前

    如果您想要一组包含NS类型的常量,请考虑将它们全部放在一个单例中。

    您可以有一个头文件和多个实现文件(每个目标一个)。只要实现了所有在头文件中声明的类就可以了。

        2
  •  29
  •   jlehr    11 年前

    在Objective-C中,对象只能在堆中分配,因此无法在静态内存中创建NSArray。但是,您可以创建指向NSString常量的指针的C数组,如下所示。。。

    NSString * const kLabelNames[] = {
        @"Foo", @"Bar", @"Baz"
    };
    

    + (NSArray *)labelNames
    {
        static NSArray *names;
        if (names == nil) {
            names = [[NSArray alloc] initWithObjects:kLabelNames count:3];
        }
        return names;
    }
    

    编辑

    注意,随着ARC、grandcentraldispatch和新的数组文字语法等新技术的引入,现在有了一种更直接的方法来完成类似的任务。请注意,下面的示例还提供了更高的线程安全性,尽管最初的示例可能包含 @synchronized

    + (NSArray *)labelNames
    {
        static NSArray *names;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            names = @[@"Foo", @"Bar", @"Baz"];
        });
    
        return names;
    }
    

    然而,上面的例子并没有完全解决最初的问题。如果确实需要一个全局常量数组,则可以按照与原始答案类似的行重写前面的示例,同时仍然利用GCD:

    NSString * const kLabelNames[] = {
        @"Foo", @"Bar", @"Baz"
    };
    
    + (NSArray *)labelNames
    {
        static NSArray *names;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            names = [NSArray arrayWithObjects:kLabelNames count:3];
        });
    
        return names;
    }
    
        3
  •  7
  •   AmitP    11 年前

    这里有一个更简单的方法:

    用逗号分隔的元素(或任何您想要的分隔符)声明NSString

    NSString *const kLabelNames = @"Foo,Bar,Baz";
    

    然后在需要时转换为NSArray:

    NSArray *namesArray = [kLabelNames componentsSeparatedByString:@","];
    
        4
  •  5
  •   veegee    10 年前

    #define SOME_ARRAY (@[@"blah", @"asdf", @"qwerty"])
    
        5
  •  2
  •   TechZen    15 年前

    如果您经常使用它,您可以创建一个协议来定义方法名。然后交换在每个目标中实现协议的类,以便同一代码根据需要返回不同的值。

        6
  •  1
  •   StilesCrisis    11 年前

    如果要避免对每个用法执行NULL检查,可以将NSObject+initialize方法分为子类。第一次实例化类时(如果实例化了任何子类,则每个子类都会调用一次),这是进行此类初始化的好地方。

    http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html%23//apple_ref/occ/clm/NSObject/initialize