3

I am new to Objective-C and come from a Java background. I have just gone over casting in Objective-C but the book I am using failed to explain the use of the '*'/pointer when casting. Here is the example they gave me:

myFraction = (Fraction *) fraction;

Aren't pointers for specific objects so they have their own unique memory location? So then why must I use a pointer when simply referencing a class? In this case, Fraction.

Thanks I hope this makes sense and I know this is a simple question that I should know and understand but I could find nothing explaining this.

jer_francis
  • 153
  • 1
  • 11
  • 3
    Please, please, please learn C or C++ before tackling Objective-C. You need to understand how pointers work, and Objective-C is not a good platform for learning that. – Hot Licks Feb 25 '14 at 21:23
  • 1
    [Why are the objects we create pointers?](http://stackoverflow.com/questions/3044292/why-most-of-the-objects-we-create-in-iphone-are-pointers) is also a good one. – jscs Feb 25 '14 at 21:30
  • I don't think this question is a duplicate of "Objective-C and Pointers" – and that question has poor answers (the accepted one is just links). It's a legitimate point of confusion for people new to Objective-C that an "object" is actually always a "pointer-to-an-object". – James Feb 25 '14 at 21:58
  • @James - It should not be a point of confusion at all for someone coming from C or C++, and a basic familiarity with those is a requirement to start programming Objective-C. – Hot Licks Feb 25 '14 at 22:56
  • @Josh Caswell No I understand why we need pointers for OBJECTS but not for references to classes. – jer_francis Feb 27 '14 at 12:17
  • You're not referencing a class in your question. You're telling the compiler the type of an object. – jscs Feb 27 '14 at 19:11

4 Answers4

3

The * symbol has multiple meanings (beside multiplication :):

  1. Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.

    (*pointerToInt) = 5;
    
  2. Declares a pointer type. When you write int * it means “reference to an integer”.

    int x = 5;
    int * xPtr = &x
    

Now, objects are a kind of structures, but we only manipulate with them via pointers. Never directly. This basically means, that 99% of time when you see * (and it's not multiplication :) it is the second case: a part of type declaration:

  • NSString * = pointer to NSString structure (you can't use NSString alone)
  • Fraction * = pointer to Fraction structure and Fraction structure is described in Fraction class

So it's not “pointer to the Fraction class”, but rather “pointer to structure of Fraction class”.


I will go a little further and answer your future question about two **. You may see this usually with NSError arguments that are defined like methodWithError:(NSError **)errorPtr.

Short story: int is to int * as NSError * is to NSError **.

Long story: If we cannot manipulate with objects directly (without pointers to them), the single pointer becomes standard part of declaration. Now what if we want to make indirect access to the object? We use double pointer! First * is required for object, second is for indirection.

NSError *error = nil; // Empty.
NSError **errorPtr = &error; // Reference to our local `error` variable.

[data writeToURL:URL options:kNilOptions error:errorPtr];
// That method uses:   (*errorPtr) = [NSError errorWith...];

NSLog(@"Error: %@", error); // Our local error is no longer empty.

I believe pointers are weird when you come from Java. They are a bit of legacy from C, but they are not used in any crazy way.

Tricertops
  • 8,492
  • 1
  • 39
  • 41
2

The * symbol is simply syntax that's used when referring to pointers.

Here, myFraction, and fraction are both variables that hold pointers (they aren't objects themselves – in fact you never have variables that hold Objective-C objects, objects must always be referred to with pointers).

The (Fraction*) syntax describes a cast to a pointer-to-a-Fraction of the expression on its right (in this case the fraction variable).

James
  • 24,676
  • 13
  • 84
  • 130
1

Remember that a pointer is just a variable that holds a memory location.

In Objective-C, when you have an object, what you really have is a pointer to an object, that is, a variable whose value is the memory address where the object really is.

Casting a pointer to a pointer of another type has no effect at runtime (at least for objects). In fact all your objects could be of type (void *). The casting helps the compiler to know what kind of object the pointer is pointing to, and generate errors or warnings.

If these two little paragraphs don't make much sense to you right now, consider reading some basic information or tutorials on pointers. Understanding pointers can be challenging for a beginner or from someone transitioning form the Java world.

Merlevede
  • 8,140
  • 1
  • 24
  • 39
1

...failed to explain the use of the '*'/pointer when casting...

Pointers have little to do with casting, other than being part of a type specifier. Consider:

  • Fraction is a type -- for the sake of argument, let's imagine that it's the name of a class, and that Fraction is a subclass of another class called Number.

  • Fraction * is a pointer to an instance of the Fraction class. In Objective-C, you always use pointers to refer to objects, so you'll see a lot of variables with types of the form ClassName *.

Casting is simply a matter of telling the compiler that it should treat a variable as a certain type. So, let's say you've got a variable number of type Number * and you know that the object it points to is actually a Fraction. However, you can't use any of the methods that are specific to Fraction because, as far as the compiler is concerned, number is just a Number *. You can use a type cast to tell the compiler: "I know what I'm doing, and number is definitely pointing to an instance of Fraction, so please treat number as a Fraction *." You do it like this:

Fraction *f = (Fraction *)number;

But again, the * doesn't have any special significance in the casting operation beyond the fact that Fraction * is the type to which you're casting number.

Caleb
  • 124,013
  • 19
  • 183
  • 272