我试图围绕 C 与 Objective-C 在用法和语法上的一些差异展开思考。特别是,我想知道 C 与 Objective-C 中点运算符和箭头运算符的用法有何不同(以及为什么)。这是一个简单的例子。
C 代码:
// declare a pointer to a Fraction
struct Fraction *frac;
...
// reference an 'instance' variable
int n = (*frac).numerator; // these two expressions
int n = frac->numerator; // are equivalent
Objective-C 代码:
// declare a pointer to a Fraction
Fraction *frac = [[Fraction alloc] init];
...
// reference an instance variable
int n = frac.numerator; // why isn't this (*frac).numerator or frac->numerator??
那么,看看 frac
在两个程序中是如何相同的(即它是一个指向 Fraction 对象或结构的指针),为什么它们在访问属性时使用不同的语法?特别是,在 C 中,numerator
属性使用 frac->numerator
访问,但在 Objective-C 中,使用点运算符访问它,使用 frac .numerator
。既然 frac
在两个程序中都是一个指针,为什么这些表达式不同呢?谁能帮我澄清一下?
最佳答案
frac
实际上在两个程序中并不相同。
C Fraction
是一个 struct
,它是一个没有重载运算符的基本类型,并且只能在默认情况下真正构造和销毁。如果您在结构上定义函数或字段,则在 C
中访问这些属性的方法是使用点 (.
) 运算符。当你使用 struct
s 时,Objective-C 会维护这个操作符。为方便起见,您可以使用箭头 (->
) 运算符(您提到的两个等效表达式)执行取消引用和点操作。 Objective-C 在访问 struct
s 时也保留了这一点。
然而,在您的示例中,Objective-C Fraction
可能(人们会假设)至少是 id
类型的指针,它只是一个类名和指针到引擎盖下的那个类的实例。它也很可能是 NSObject
或 NSProxy
的子类。这些 Objective-C 类的特殊之处在于它们在 C
结构之上有一整层预定义的操作(如果你真的想深入研究它,那么你可以看看 Objective-C Runtime Reference ) .另外需要注意的是,Objective-C 类总是一个指针。
最基本的操作之一是 objc_msgSend
。当我们对这些类型的对象进行操作时,Objective-C 编译器将点 (.
) 运算符或方括号语法 ([object method]
) 解释为 objc_msgSend
方法调用。有关此处实际发生的情况的更多详细信息,请参阅负责 Obj-C 运行时开发的 Apple 工程师 Bill Bumgarner 的 this series of posts。
箭头 (->
) 运算符实际上不应该用于 Objective-C 对象。就像我说的,Objective-C 类实例是一个 C 结构,添加了额外的通信层,但是当您使用箭头时,该通信层基本上被绕过了。例如,如果你打开 Xcode 并输入 [UIApplication sharedApplication]->
然后调出方法完成列表,你会看到:
在这里你可以看到一堆我们通常使用方括号语法访问的普通字段(如[[UIApplication sharedApplication] delegate]
)。然而,这些特定的项目是 C
字段,用于存储它们各自的 Objective-C 属性的值。
所以,你大致可以这样想:
C 对象上的点运算符
- (运行时)字段的返回值
C 对象(指针)上的箭头运算符
- 取消引用指针
- 字段的返回值
Objective-C 对象(指针)上的点运算符/方括号
- (在编译时)替换为对
objc_msgSend
的调用
- (在运行时)查找 Obj-C 类定义,如果出错则抛出异常
- 取消引用指针
- 字段的返回值
Objective-C 对象(指针)上的箭头运算符
- (在运行时)取消引用指针
- 字段的返回值
现在我在这里肯定过于简单化了,但总结一下:箭头运算符在两种情况下看起来基本相同,但点运算符在 Objective-C 中具有额外/不同的含义。
关于objective-c - 点 (".") 运算符和箭头 ("->") 运算符在 C 与 Objective-C 中的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9072688/