【Objective-C】点(".")运算符和箭头("->")运算符在C与Objective-C中的使用

我正在试图理解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

O-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在两个程序中是如此相同(即它是指向片段对象或结构的指针),那么为什么它们在访问属性时使用不同的语法呢?特别是,在C中,numerator属性是通过frac->numerator访问的,但在Objective-C中,它是通过frac.numerator使用点运算符访问的。既然frac在两个程序中都是指针,为什么这两个表达式是不同的呢?有人能帮我弄清楚这一点吗?

 

回答:

在这两个程序中,frac实际上并不相同。

C Fraction是一个struct,它是一个没有重载操作符的基类型,并且只能在默认情况下被构造和析构。如果在结构上定义函数或字段,则在C中访问这些属性的方法是使用点(.)运算符。当您使用structs时,Objective-C会维护此运算符。为方便起见,您可以使用箭头(->)运算符(您提到的两个等效表达式)来执行解引用和点操作。Objective-C在访问struct时也保留了这一点。

然而,在您的示例中,Objective-C Fraction可能(假设)至少是一个id类型的指针,它只是一个类名和隐藏在幕后的指向该类实例的指针。它也很可能是NSObjectNSProxy的子类。这些Objective-C类的特殊之处在于,它们在C结构之上有一整层预定义的操作(如果您真的想深入研究它,那么可以看看Objective-C Runtime Reference)。同样需要注意的是,Objective-C类始终是一个指针。

最基本的操作之一是objc_msgSend。当我们对这些类型的对象进行操作时,Objective-C编译器将点(.)运算符或方括号语法([object method])解释为objc_msgSend方法调用。有关这里实际发生了什么的更多详细信息,请参阅Bill Bumgarner的this series of posts,他是一名苹果工程师,负责Obj-C运行时的开发。

箭头(->)运算符实际上不应该用于Objective-C对象。正如我所说的,Objective-C类实例是一个添加了额外通信层的C结构,但当您使用箭头时,该通信层基本上会被绕过。例如,如果您打开Xcode并键入[UIApplication sharedApplication]->,然后打开方法完成列表,您将看到以下内容:

在这里你可以看到一堆普通的字段,我们通常使用方括号语法来访问它们(比如[[UIApplication sharedApplication] delegate])。然而,这些特定的项是存储它们各自的Objective-C属性的值的C字段。

所以,你可以大致这样想:

C对象上的点运算符

  1. (运行时)字段的返回值

C对象(指针)上的箭头运算符

  1. 取消引用字段的值

Objective-C对象(指针)上的点运算符/方括号

Obj运行时(在编译时)替换为对objc_msgSend

  • (at运行时的调用)查找Obj-C类定义,如果wrong
  • Dereference pointer
  • Return的值为1,则抛出异常

Objective-C对象(指针)上的箭头运算符

  • Return
  • (在运行时)取消引用字段的值

现在我在这里绝对是过于简化了,但总结一下:箭头操作符似乎在两种情况下做的事情基本上是一样的,但是点运算符在Objective-C中有一个额外的/不同的含义。

 

转载自:https://cloud.tencent.com/developer/ask/sof/96619

posted @ 2022-08-01 17:24  Jerry2km1  阅读(396)  评论(0)    收藏  举报