0

Let's imagine I have Fraction class. So, the correct way to create instance of it is:

Fraction *myFraction;
or
myFraction = Fraction;
or
myFraction = [Fraction new];

or something else?

In the book i'm studying the correct one is first, but it looks unreasonable to me. Why do we have to create a pointer for it? Why don't we make the real instance?

That first expression means - give me a pointer to the new instance of Fraction class, doesn't it?

1
  • Note you can format lines as code by indenting them four spaces. The "{}" button in the editor toolbar does this for you. Edit your question and try it out. Click the orange question mark in the editor toolbar for more information and tips on formatting. Commented Apr 23, 2011 at 9:02

3 Answers 3

4

The first declares a variable named myFraction of type Fraction *, but doesn't create anything, nor initialize myFraction. The second isn't valid. The third creates a new Fraction and assigns it to a previously declared variable named myFraction. Often in Objective-C, you'll declare and initialize a variable in a single statement:

Fraction *myFraction = [[Fraction alloc] init];

As for whether to use new or alloc followed by init, it's largely a matter of taste.

Variables for storing objects are pointers in part because Objective-C inherited C's call-by-value semantics. When one variable is assigned to another (such as when passing it to a function), the value will be copied. At best, this is inefficient for immutable objects. At worst, it leads to incorrect behavior. Pointers are a way around call-by-value and the copy-on-assign semantics: the value of a variable with pointer type is just the pointer. It can be copied without touching the target object. The cost for this is you need some form of memory management.

Sign up to request clarification or add additional context in comments.

Comments

3

It would be a good idea to read Kernihan and Ritchie's "The C Programming Language" so you can get an idea about how variables are declared.

There are two modes of allocation in C and Obj-C and C++: manual and automatic.

Integers and floats and characters and such are generally automatically declared. They are created when the declaration passes (i.e. int i), and deleted when the scope they were created in goes away, i.e. when you exit the block in which they were declared. They're called automatics. (it's also possible to declare them "static" but for the purposes of this discussion regarding allocation, these are the same)

Objects are too complicated to pass around to functions, as function parameters are "pass by value", meaning that the parameter gets a copy of the value being passed in, instead of the variable itself. It'd take a huge amount of time to copy a whole object all the time.

For this reason, you want to just tell the various functions where they can find the object. Instead of handing off a copy of the object, you hand off a copy of the address of the object. The address is stored in an automatic with a type of pointer. (This is really just an integer, but it's size is dictated by the hardware and OS, so it needs to be a special type.)

The declaration Fraction *myFraction; means "myFraction is a pointer, and just so you know, it's going to point to a Fraction later."

This will automatically allocate the pointer, but not the whole Fraction. For that to happen, you must call alloc and init.

The big reason why you have this two step process is that since we typically want objects to stick around for a while, we don't want the system automatically killing them at the end of a function. We need them to persist. We create places to hang the object in our functions, but those hangers go away when they aren't needed. We don't want them taking the object with them.

Ultimately, you might make declarations like this:

Fraction *myFraction = [[Fraction alloc] initWithNumerator: 2 Denominator: 3];

which says: "Make me a Fraction, and set it to be 2/3, and then put the address of that Fraction into 'myFraction'."

Comments

0

Why do we have to create a pointer for it? Why don't we make the real instance?

In Objective-C, every object is pointer type. So, you need to use either new or alloc/init.

Fraction *myFraction = [ Fraction new ] ;

or

Fraction *myFraction = [ [Fraction alloc] init ] ;

And myFraction needs to be released.

That first expression means - give me a pointer to the new instance of Fraction class, doesn't it?

No, you are just declaring a pointer of type Fraction. And the second statement is not even valid.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.