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

标签 objective-c c pointers dot-operator

我试图围绕 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 .nu​​merator。既然 frac 在两个程序中都是一个指针,为什么这些表达式不同呢?谁能帮我澄清一下?

最佳答案

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

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

然而,在您的示例中,Objective-C Fraction 可能(人们会假设)至少是 id 类型的指针,它只是一个类名和指针到引擎盖下的那个类的实例。它也很可能是 NSObjectNSProxy 的子类。这些 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]-> 然后调出方法完成列表,你会看到:

A list of internal ivars on an Obj-C object when using the arrow operator

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

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

C 对象上的点运算符

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

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

  1. 取消引用指针
  2. 字段的返回值

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

  1. (在编译时)替换为对 objc_msgSend
  2. 的调用
  3. (在运行时)查找 Obj-C 类定义,如果出错则抛出异常
  4. 取消引用指针
  5. 字段的返回值

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

  1. (在运行时)取消引用指针
  2. 字段的返回值

现在我在这里肯定过于简单化了,但总结一下:箭头运算符在两种情况下看起来基本相同,但点运算符在 Objective-C 中具有额外/不同的含义。

关于objective-c - 点 (".") 运算符和箭头 ("->") 运算符在 C 与 Objective-C 中的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9072688/

相关文章:

c - 从指针到 char 返回正确的变音字符?

c - 我将如何读取一行,解析信息,然后将其归因于 C 中的结构?

函数中的 C 指针

objective-c - Cocoa:中断每个方法调用?

objective-c - 按下或禁用时不要更改 NSButton 的外观

c - 使用 cws2fws 转换压缩的 swf 时出现问题

c - 每 0.008 秒从 MATLAB Simulink 获取 .txt 文件中的数据

c - 我正在尝试在 shell 环境中从 C 中的文件中执行读取行

创建核心基础类

ios - 自定义注释 View 未显示在 map 上