Reputation: 1
Please spare me if this is a newbie question, I'm coming from Java and the concept of pointers just seems foreign to me.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
So... the code is telling me that skView is a pointer but you can access the object that the pointer is pointing to. Shouldn't the code below the correct way to do it because *skView means that you are accessing the actual object the pointer is pointing to?
*skView.showsFPS = YES;
*skView.showsNodeCount = YES;
Here is The C Programming Language guide to pointers
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] */
It's saying that you need to use that *ip keyword in order to access the value of the pointer? I'm just confused here...
Upvotes: 0
Views: 73
Reputation: 53010
You write:
I'm coming from Java and the concept of pointers just seems foreign to me.
Objects in both Java and Objective-C are reference types; that is a variable of object type holds a reference (or pointer or address) to an object structure created elsewhere. This is in contract to value types, such as int
, where the contents of a variable of value types is a representation of the actual value.
The difference between Java and Objective-C is that the latter makes the reference/pointer part visible in the declaration using a *
, following on from C.
Consider the following Java fragment:
class MyClass { ... }
MyClass one = new MyClass ();
MyClass two = one;
MyClass three;
After this as a Java programmer you will know that: one
references a new instance of MyClass
; two
references the same object as one
and not a copy of the object that one
references; and three
is either undefined or null
depending on what kind (field, local) variable it is.
Objective C works exactly the same way, the equivalent code:
@interface MyClass
...
@end
MyClass *one = [MyClass new];
MyClass *two = one;
MyClass *three;
and the three variables have the same values (three
will always be nil
under ARC and never undefined regardless of variable kind).
The reference (pointer) indicator *
is only present in the type of object variables in Objective-C; as in Java, but unlike in C, following the reference to the object ("dereferencing") is automatic. So in Java you might write:
one.equals(two)
to invoke the equals
method while in Objective-C it would be:
[one isEqual:two]
For properties in Objective-C; that is two methods, a setter and a getter, which together have like a variable; a dot shorthand may be used:
int x = one.intProperty; // equivalent to int x = [one intProperty];
one.intProperty = 42; // equivalent to [one setIntProperty:42];
This is not the same a C's use of .
for structure field access, though is similar and hence uses the same syntax.
If a class in Objective-C has public instance variables, which should generally be avoid in favour of properties as part of good encapsulation, then these are accessed using the ->
operator that C uses to access fields from a pointer to a struct:
one->instanceVariable
and as with C you can make the deference explicit with:
(*one).instanceVariable
but there is never any need to do this and it is best avoided.
I think that answers all the questions you posed.
Upvotes: 1
Reputation: 25926
For regular C, you're sort-of correct.
If you were to do something like this:
struct my_struct {
int a;
int b;
};
struct my_struct my_object = {1, 2};
struct my_struct * my_ptr = &my_object;
then you can access the members by dereferencing the pointer:
int n = (*my_ptr).a;
or without dereferencing it by using the ->
operator:
int n = my_ptr->a;
But the dot-syntax you see with Objective-C is something different to this. The compiler knows you're dealing with an Objective-C object, and transforms it into a message call.
It one sense, it's slightly unfortunate that Objective-C uses syntax which is the same as that you can use to access regular C struct
members, but which actually does something very different. On the other hand, that syntax was introduced precisely because it's familiar to C programmers doing something kinda-sorta similar with struct
s. Either way, it's important not to confuse the two.
Upvotes: 1
Reputation: 385860
You are confused by dot syntax.
You wrote this:
skView.showFPS = YES;
You think skView.showFPS
means “access the field showFPS
in the struct
or union
variable skView
”, because that's what it means in C (and C++).
But you are mistaken. In that statement, skView
is a pointer to an Objective-C object. When the compiler sees a dot after a pointer-to-object, it transforms the expression in one of two ways.
If the expression is the left-hand side of an assignment, as in your example, then it transforms the expression to this:
[skView setShowFPS:YES];
On the other hand, suppose the expression is not the left-hand side of an assignment. For example:
BOOL showingFPS = skView.showFPS;
Then the compiler transforms the expression like this:
BOOL showingFPS = [skView showFPS];
In other words, the compiler transforms dot notation (when applied to an object pointer) into either a getter or setter message, depending on the context.
I've omitted some details in the explanation. You can override the names of the getter and setter messages if you want, using an @property
declaration.
If you really want to access an instance variable of an object directly, and the declaration of the instance variable is visible to you, you can do this:
skView->_showFPS = YES;
or equivalently this:
(*skView)._showFPS = YES;
(Note that .
binds more tightly than prefix *
, so you need the parentheses.)
However, this is almost always a bad idea. You should almost never access an object's instance variables directly from outside the object. And even inside an object's implementation, it's often better to use properties with accessor methods instead of naked instance variables.
Upvotes: 2