user3693386
user3693386

Reputation: 1

When you declare a pointer does that make a new object?

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

Answers (3)

CRD
CRD

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

Crowman
Crowman

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 structs. Either way, it's important not to confuse the two.

Upvotes: 1

rob mayoff
rob mayoff

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

Related Questions