objective-c – 为什么NSNumber文字不能用于静态声明

前端之家收集整理的这篇文章主要介绍了objective-c – 为什么NSNumber文字不能用于静态声明前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我宣布:
static NSString *a = @"a";

这是iOS6中的正确声明(使用编译器版本应该更正确,但目前我还不知道).我认为数字文字也是:

static NSNumber *b=@1;

可能是一个有效的声明.编译器告诉我初始化元素不是编译时常量.这让我感到惊讶.因为NSNumber是不可变的NSString,因为我在字符串的情况下使用文字,我认为它也可以是有效的.

有没有人对这种差异有合理的解释?

解决方法

第一行是编译时常量,因为你分配@“a”而不是像静态NSString * a = [NSString stringWithFormat:@“a”];(这将抛出相同的错误)

但对于NSNumber,静态NSNumber * b = @ 1;实际上相当于静态NSNumber * b = [NSNumber numberWithInt:1] ;.有关详细信息check Objective-C Literals.

请注意,在上述情况下,右侧不是编译时常量.它是一个必须在运行时计算的表达式.在C和Objective-C中,必须使用编译时常量初始化静态变量.

如果你想将NSNumber作为const,你可以检查这里提到的方法Objective C – How to use extern variables?.

也是check this on Objective C literals from Mike Ash,

It’s important to note that none of the new literal Syntax qualifies
as a compile-time constant.

和,

NSString literals are also compile-time constants,because of a tight
coupling between the compiler and the libraries. There’s a special
NSString subclass called NSConstantString with a fixed ivar layout:

This tight coupling has advantages,like producing legal global
variable initializers,and requiring no extra code to run to build the
object at runtime. However,there are big disadvantages as well. The
NSConstantString layout is set forever. That class must be maintained
with exactly that data layout,because that data layout is baked into
thousands of third-party apps. If Apple changed the layout,those
third-party apps would break,because they contain NSConstantString
objects with the old layout.

If NSArray literals were compile-time constants,there would need to
be a similar NSConstantArray class with a fixed layout that the
compiler could generate,and that would have to be maintained
separately from other NSArray implementations. Such code could not run
on older OSes which didn’t have this NSConstantArray class. The same
problem exists for the other classes that the new literals can
produce.

This is particularly interesting in the case of NSNumber literals.
Lion introduced tagged pointers,which allow an NSNumber’s contents to
be embedded directly in the pointer,eliminating the need for a
separate dynamically-allocated object. If the compiler emitted tagged
pointers,their format could never change,and compatibility with old
OS releases would be lost. If the compiler emitted constant NSNumber
objects,then NSNumber literals would be substantially different from
other NSNumbers,with a possible significant performance hit.

Instead,the compiler simply emits calls into the framework,constructing the objects exactly like you would have done manually. This results in a bit of a runtime hit,but no worse than building them yourself without the new Syntax,and makes for a much cleaner design.

猜你在找的C&C++相关文章