Cha*_*les 61 c pointers objective-c 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
Run Code Online (Sandbox Code Playgroud)
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??
Run Code Online (Sandbox Code Playgroud)
那么,看看frac两个程序中的相同情况(即它是指向Fraction对象或结构的指针),为什么它们在访问属性时使用不同的语法?特别是,在C中,numerator可以访问属性frac->numerator,但是使用Objective-C,可以使用点运算符访问它frac.numerator.既然frac是两个程序中的指针,为什么这些表达式不同?任何人都可以帮我澄清一下吗?
dar*_*s0n 78
frac 在两个程序中实际上并不相同.
AC Fraction是a struct,它是一个没有重载运算符的基类型,默认情况下只能构造和销毁.如果在结构上定义函数或字段,C则使用dot(.)运算符访问这些属性的方法.当您使用structs 时,Objective-C维护此运算符.为方便起见,您可以使用arrow(->)运算符(您提到的两个等效表达式)执行取消引用和点操作.Objective-C在访问structs 时也保留了这个.
Fraction但是,你的例子中的Objective-C 可能(人们会假设)至少id是一个类型的指针,它只是一个类名和指向该类实例的指针.它也很可能是NSObject或的子类NSProxy.这些Objective-C类的特殊之处在于它们只在一个C结构体上有一整层预定义操作(如果你真的想深入研究它,那么你可以看看Objective-C运行时参考).同样重要的是,Objective-C类始终是指针.
最基本的操作之一是objc_msgSend.当我们对这些类型的对象进行操作时,Objective-C编译器会将dot(.)运算符或方括号语法([object method])解释为objc_msgSend方法调用.有关这里实际发生的更多详细信息,请参阅负责监督Obj-C运行时开发的Apple工程师Bill Bumgarner撰写的这一系列文章.
->实际上不应该在Objective-C对象上使用arrow()运算符.就像我说的,Objective-C类实例是一个C结构,添加了额外的通信层,但是当你使用箭头时,这个通信层基本上被绕过了.例如,如果您打开Xcode并键入[UIApplication sharedApplication]->然后调出方法完成列表,您会看到:

在这里,您可以看到一堆普通字段,我们通常使用方括号语法(如[[UIApplication sharedApplication] delegate])进行访问.但是,这些特定项C是存储其各自Objective-C属性值的字段.
所以,你可以大致这样想:
C对象上的点运算符
C对象上的箭头操作符(指针)
Objective-C对象上的点运算符/方括号(指针)
objc_msgSendObjective-C对象上的箭头运算符(指针)
现在我肯定在这里过分简化了,但总结一下:在两种情况下,箭头运算符似乎都基本相同,但点运算符在Objective-C中具有额外/不同的含义.
点符号是一种设计选择.因为我们总是处理指向objc实例的指针,所以我猜设计师想要一些熟悉的东西,这也不会破坏现有的程序.它是在几年前的ObjC 2中引入的.在此之前,您总是必须使用括号进行消息传递.
点符号虽然有所不同 - 它不是直接访问,而是消息.
那是:
obj.property = val;
// is the same as:
[obj setProperty:val];
// and not:
obj->property = val;
val = obj.property;
// is the same as:
val = [obj property];
// and not:
val = obj->property;
Run Code Online (Sandbox Code Playgroud)
您仍然可以编写obj->ivar以访问指向对象成员的指针(如果可见).
在您的第一个示例中,Fraction是一个结构.在你的第二个例子中,Fraction是一个Objective-C类(在iOS中可能是它的子类NSObject).
C++ 不允许重载operator ..因此,如果没有其他信息,您可以推断出您所看到的点符号是集成到Objective-C中的附加语言构造,而不是C/C++定义或重载的运算符.
实际上,点符号只是实现者选择作为属性访问速记的设计特征,完全等同于方括号getter:
myObjCVar.prop == [myObjCVar prop];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51300 次 |
| 最近记录: |