Obj-C中的NSNumber常量

时间:2012-09-04 17:55:45

标签: objective-c ios constants nsnumber

我想通过this topic中用于NSStrings的相同样式制作一些NSNumber常量。也就是说,我正在创建单独的constants.h / .m文件并将它们导入需要访问它们的类中。

4 个答案:

答案 0 :(得分:18)

这样做的麻烦在于没有编译时常量NSNumber这样的东西。只有NSString才能获得这种区别。 NSNumbers始终是动态创建的。您可以使用在程序启动时运行的函数来伪造它以初始化变量。你的选择:

  1. 使用+load方法创建一个执行初始化的类。

  2. 在包含常量的文件中,包含一个__attribute__((constructor))的函数。所以,例如:

    // Constants.m
    
    NSNumber *someGlobalNumber;
    
    __attribute__((constructor))
    static void InitGlobalNumber() {
        someGlobalNumber = [[NSNumber numberWithInteger:1] retain];
    }
    
  3. 但是当然,您无法在启动过程早期运行的任何其他功能中可靠地使用这些数字。这通常不是问题,但值得记住。

    另一个选项,我已经看过几次,是为了让一个类具有数字访问器,而不是给变量提供原始访问权限。这是一个更重的设计,但它也感觉不那么巫术,它有它的魅力。

答案 1 :(得分:16)

不幸的是,您当前无法生成NSNumber常量,就像生成NSString常量一样。当您尝试这样做时,您将收到编译器错误

NSNumber * const kNumberConstant = @2; // This doesn't work.

但是,您可以使用原语。

NSInteger const kSomeIntValue = 10;

答案 2 :(得分:5)

你基本上可以在三个方面达到你想要的效果:

.h文件:

extern NSNumber *MyFirstConstant;

.m文件

NSNumber *MyFirstConstant;

AppDelegate.m

+(void)initialize
{
    MyFirstConstant = @5;
    ...
}

AppDelegate保证在您的任何其他代码之前运行,并且初始化是在AppDelegate上调用的第一个方法,因此您可以基本上确保在应用程序运行之前为您设置所有常量。

答案 3 :(得分:4)

更新

多年以后,我才意识到 可以为整数创建一个NSNumber常量......但这是一个黑客攻击:

#define CONST_INT_NSNUMBER( x ) ((__bridge NSNumber * const)(void * const)(( x << 8 ) | 0x27))


NSNumber * const number = CONST_INT_NSNUMBER(123) ;

这是有效的,因为某些整数NSNumber存储为tagged pointers


原始答案:

你不能这样做。

NSNumber * const mynumber = @5.5;

给出:

  

Initializer元素不是编译时常量

暗示编译器有一个特殊的功能,专门用于创建编译时常量NSString对象,而不是任何其他类型的对象。

可以这样做,但是:

<强>·H

extern NSNumber * kConstantNumber ;

<强>的.m

NSNumber * kConstantNumber ;

@implementation NSNumber (InitializeConstants)

+(void)load
{
    kConstantNumber = @42;
    // ... and the rest ...
}

@end