如果您有一个静态const字符串,那么它的使用可能会导致编译器解释不一致。例如,在这种情况下:
const NSString* kUntitled = @"Untitled";
NSString* title = kUntitled;
编译器会抱怨将const指针指定给非常量指针("丢弃限定符"),并且可能是正确的。这可以通过完全不使用const
或通过调用kUntitled.copy
来解决(我不知道类似于类型转换(NSString*)kUntitled
的想法)
但是,如果您改为:
NSString* title = aTitle ?: kUntitled;
然后编译器没有抱怨。
我的第一个问题是,在第一个例子中可以忽略警告吗?将const NSString分配给非常量的NSString是否存在潜在的危险?
其次,为什么编译器会忽略三元运算符的情况?
答案 0 :(得分:2)
警告是const NSString * kUntitled
不正确这一事实的副作用。这是一个指向readonly的指针 - NSString
。注意那里“只读”的位置 - 它指的是字符串,而不是指针。但ObjC对象永远不会只读,永远不会const
。当然,你可以说文字NSString
s ,但那是implementation dependent,甚至可以在某些运行时环境中修改。
因此,您永远无法在其他任何地方正确地分配此对象(除非该变量也是指向const
对象的指针)。
您应该使用的声明是NSString * const kUntitled
- 这是“readonly-pointer-to - NSString
”,即指针无法更改为指向在另一个对象。
答案 1 :(得分:2)
欢迎来到奇怪而美妙的C宣言世界 - 测验问题的内容; - )
const NSString* kUntitled = @"Untitled";
你可能没有在这里写下你的意图。这将kUntitled
定义为可变指向“常量”字符串的指针 - 通常称为“指向常量”的指针......但是它仍然是“常量”的原因尽管如此常见的“指向常量的指针”它实际上是一个“只读指针”,这意味着你可以通过指针读取但是不能写,指向的可能是可变的但它不是可变的如果是这样的话......
困惑?以上所有意味着你以后可以写:
kUntitled = @"oops you probably thought you couldn't assign";
由于指针本身是可变的,因此可以将其更改为指向其他内容。
你可能想要的是:
NSString * const kUntitled = @"Untitled";
声明常量指向字符串的指针 - 它是指针本身,不能改变:
kUntitled = @"this will produce a compile error, can't change a constant";
如果您使用此版本的声明,那么您的作业不会出现错误:
NSString* title = kUntitled; NSString* title = aTitle ?: kUntitled;
然而,这仍然留下了为什么你没有从你的原始声明中获得第二个错误的问题......
作业的RHS,aTitle ?: kUntitled
实际上是有效的,再次是C的奇怪世界。此表达式只是aTitle ? aTitle : kUntitled
的简写,并且C语言中此运算符的规则,第二个和第三个参数可以是相同的基本指针类型,在您的情况下为NSString *
,但不同< / em>在限定符中,在您的情况下为const
,结果类型是基本指针类型,其中 all 是两个操作数的限定符。
换句话说,此表达式的结果被视为const NSString *
。这意味着你应该得到与第一次任务相同的警告。
似乎编译器正在将运算符视为结果类型是基本指针类型,其中 none或只有两个操作数的公共限定符 - 即相反定义。
因此,对于第二个问题,您可能发现了编译器错误,您应该将其报告给Apple(bug reporter.apple.com),看看他们说了什么。
HTH