簡體   English   中英

如何將NSArray用作全局常量?

[英]How can I use an NSArray as a global constant?

我正在使用一組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`也不起作用。 這是因為我的數組中的字符串不是常量嗎?

如何將數組設置為全局常量? 謝謝。

在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,Grand Central Dispatch等新技術的引入以及數組的新文字語法,現在有一種更簡單的方法可以實現類似的功能。 請注意,下面的示例還提供了更高的線程安全性,盡管原始示例可能包含@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;
}

這是一個更簡單的方法:

用逗號分隔的元素(或任何你想要的分隔符)聲明NSString

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

然后在需要時轉換為NSArray:

NSArray *namesArray = [kLabelNames componentsSeparatedByString:@","];

如果你想要一組包含NS類型的常量,可以考慮將它們全部放在一個單例中。

您可以擁有一個頭文件和多個實現文件(每個目標一個)。 只要這一切都實現了頭文件中聲明的類,你應該沒問題。

使用宏:

#define SOME_ARRAY (@[@"blah", @"asdf", @"qwerty"])

您應該創建一個包含類方法中常量的類。 然后,您可以將類添加到任何目標,並調用方法以獲取對象(如數組)中的常量。 改變類或類實現來改變常量的返回。

如果您經常使用它,您可以創建一個定義方法名稱的協議。 然后換出在每個目標中實現協議的類,以便相同的代碼根據需要返回不同的值。

如果要避免對每次使用進行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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM