如果这是一个新手问题,请饶恕我,我来自Java,指针的概念对我来说似乎很陌生。
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
所以......代码告诉我skView是一个指针,但你可以访问指针所指向的对象。不应该以正确的方式执行代码,因为* skView意味着您正在访问指针指向的实际对象吗?
*skView.showsFPS = YES;
*skView.showsNodeCount = YES;
这是指针的C编程语言指南
int x = 1, y = 2, z[10];
int *ip; /* ip is a pointer to int */
ip = &x; /* ip now points to x */
y = *ip; /* y is now 1 */
*ip = 0; /* x is now 0 */
ip = &z[0]; /* ip now points to z[0] */
它说你需要使用那个* ip关键字才能访问指针的值?我在这里很困惑......
答案 0 :(得分:2)
您对dot syntax感到困惑。
你写了这个:
skView.showFPS = YES;
您认为skView.showFPS
表示“访问showFPS
或struct
变量union
中的字段skView
”,因为这就是C中的含义(和C ++)。
但你错了。在该语句中,skView
是指向Objective-C对象的指针。当编译器在指向对象的指针之后看到一个点时,它会以两种方式之一转换表达式。
如果表达式是赋值的左侧,如示例所示,那么它将表达式转换为:
[skView setShowFPS:YES];
另一方面,假设表达式不分配的左侧。例如:
BOOL showingFPS = skView.showFPS;
然后编译器将表达式转换为:
BOOL showingFPS = [skView showFPS];
换句话说,编译器将点表示法(当应用于对象指针时)转换为getter或setter消息,具体取决于上下文。
我在解释中省略了一些细节。如果需要,您可以覆盖getter和setter消息的名称,using an @property
declaration。
如果您确实想直接访问对象的实例变量,并且您可以看到实例变量的声明,则可以执行以下操作:
skView->_showFPS = YES;
或等效地:
(*skView)._showFPS = YES;
(注意.
比前缀*
绑定得更紧,所以你需要括号。)
但是,这几乎总是一个坏主意。您几乎不应该直接从对象外部访问对象的实例变量。甚至在对象的实现中,使用带有访问器方法的属性而不是裸实例变量通常更好。
答案 1 :(得分:1)
对于常规C,您的排序是正确的。
如果你要做这样的事情:
struct my_struct {
int a;
int b;
};
struct my_struct my_object = {1, 2};
struct my_struct * my_ptr = &my_object;
然后您可以通过取消引用指针来访问成员:
int n = (*my_ptr).a;
或不使用->
运算符取消引用它:
int n = my_ptr->a;
但是你用Objective-C看到的点语法与此不同。编译器知道您正在处理Objective-C对象,并将其转换为消息调用。
从某种意义上说,Objective-C使用的语法与您可以用来访问常规C struct
成员的语法相同,但实际上做了一些非常不同的事情,这有点令人遗憾。另一方面,正确引入该语法是因为C语言程序员所熟悉的事情与struct
s类似。无论哪种方式,重要的是不要混淆两者。
答案 2 :(得分:1)
你写道:
我来自Java,指针的概念对我来说似乎很陌生。
Java和Objective-C中的对象都是引用类型;这是对象类型的变量,它包含一个引用(或指针或地址)到其他地方创建的对象结构。这是与值类型的契约,例如int
,其中值类型变量的内容是实际值的表示。
Java和Objective-C之间的区别在于,后者使用*
在声明中显示引用/指针部分,从C开始。
考虑以下Java片段:
class MyClass { ... }
MyClass one = new MyClass ();
MyClass two = one;
MyClass three;
在此作为Java程序员之后,您将知道:one
引用MyClass
的新实例; two
引用与one
相同的对象,而不是one
引用的对象的副本; three
未定义或null
取决于它是什么类型(字段,本地)变量。
Objective C的工作方式完全相同,等效代码:
@interface MyClass
...
@end
MyClass *one = [MyClass new];
MyClass *two = one;
MyClass *three;
并且这三个变量具有相同的值(three
在ARC下始终为nil
,并且无论变量类型如何都不会未定义。
引用(指针)指示符*
仅出现在Objective-C中的对象变量类型中;就像在Java中一样,但与C中不同,跟随对象的引用(“解除引用”)是自动的。所以在Java中你可以写:
one.equals(two)
在Objective-C中调用equals
方法,它将是:
[one isEqual:two]
Objective-C中的属性;这是两个方法,一个setter和一个getter,它们一起就像一个变量;可以使用点速记:
int x = one.intProperty; // equivalent to int x = [one intProperty];
one.intProperty = 42; // equivalent to [one setIntProperty:42];
这与C对结构字段访问的.
的使用不同,虽然类似,因此使用相同的语法。
如果Objective-C中的类具有公共实例变量(通常应该避免使用属性作为良好封装的一部分),那么可以使用C用于访问来自a的字段的->
运算符来访问这些变量。指向结构的指针:
one->instanceVariable
和C一样,您可以使用以下方式明确表示尊重:
(*one).instanceVariable
但是从来没有必要这样做,最好避免。
我认为这回答了你提出的所有问题。