Iphone Obj-C:两者之间的区别;“费尔菲尔德”;及",;“费尔菲尔德”;(用at字符串)?

Iphone Obj-C:两者之间的区别;“费尔菲尔德”;及",;“费尔菲尔德”;(用at字符串)?,iphone,objective-c,nsstring,Iphone,Objective C,Nsstring,我刚刚在我的iPhone应用程序中输入了一个ridonkulous拼写错误 现在我想知道“…”符号 为什么会这样: NSArray *someArray = [NSArray arrayWithObjects: @"Fairfield", nil]; 这不会(即使它编译,也会抛出EXC\u BAD\u访问): 编辑: 好的,你们已经指出我不能将C字符串添加到NSArray中,因为它显然不是一个对象 现在还有一个问题:这不是有点疏忽吗?我的意思是,为什么“…WithObjects:”消息指定的是

我刚刚在我的iPhone应用程序中输入了一个ridonkulous拼写错误

现在我想知道“…”符号

为什么会这样:

NSArray *someArray = [NSArray arrayWithObjects: @"Fairfield", nil];
这不会(即使它编译,也会抛出EXC\u BAD\u访问):

编辑:

好的,你们已经指出我不能将C字符串添加到NSArray中,因为它显然不是一个对象

现在还有一个问题:这不是有点疏忽吗?我的意思是,为什么“…WithObjects:”消息指定的是(id)列表而不是(NSObject*)?

“@Fairfield”
是一个普通的C字符串,其中有一个“@”字符
@“Fairfield”
是一个Objective-C字符串(
OSX上的NSString
),其中没有文字'@'

您无法将C字符串添加到Cocoa集合。

“Fairfield”
是C字符串,
@“Fairfield”
是Objective-C字符串

@“Fairfield”
是一个对象(NSString),因此您可以向它发送方法(
[@“Fairfield”大写字符串]
)并将其添加到Objective-C数组中(
[NSArray arrayWithObjects:@“Fairfield”,nil]
)。只能将对象添加到NSArray


另一方面,
“Fairfield”
是一个C字符串,通常不用于Cocoa。在大多数情况下,您只需使用
@“Fairfield”
即可,它接受
id
而不是
NSObject
,因为所有初始化器都返回
id
。所有初始值设定项都返回
id
,因为子类将重写其祖先的初始值设定项的返回类型

例如,
-[NSMutableString init]
不能返回
NSMutableString*
,因为它是
-[NSString init]
的子类,不能返回
NSString*
,因为它覆盖了
-[NSObject init]


不幸的是,
const char*
id
之间的隐式类型转换是完全合法的,因此编译器不会抛出警告,然而,静态分析器可能能够相当容易地发现这类错误。

Cocoa中的许多东西处理
id
而不是
NSObject*
的另一个原因是,与其他一些语言(比如Java和C)不同,该语言中的所有对象都必须从某个全局基类继承,完全可以有不从
NSObject
下降的对象(例如
NSProxy
)。这不是你经常做的事,但这是可能的。
id
类型的意思是“指向任何目标C实例的指针”。

这只是对前面问题的澄清,应该被编辑成该问题。谢谢保罗——我确实想过要编辑它——但我觉得这比指出一个愚蠢的打字错误更一般,也更能提供信息。我将来会倾向于另一种选择,这完全是你的疏忽。在所有情况下,都可以安全地假定NSObject的后代。感谢您的解释。非常有用。太糟糕了,XCode中的分析器没有接收到它。。。这就解释了id的原因。我假设所有NS*对象都是NSObject的后代。一般来说,假设它们是。(与非NS*框架类一起)但这不是必须的规则。
NSArray *someArray = [NSArray arrayWithObjects: "@Fairfield", nil];