Question

Maybe this is a dumb question, but I really want to figure this one out.

For example I have the following setup:

// .h
@interface MyClass : NSObject
{
   NSView *myView;
}

// .m

@implementation MyClass

-(void)someMethod
{

   // WHAT IS THE DIFFERENCE BETWEEN THIS
   myView = [[NSView alloc] init];

   // AND THIS ?

   myView = [myView init]; // assuming that myView was allocated somewhere earlier in init method
}
Was it helpful?

Solution

init methods tend to assume that you only send init once to every object.

Sending init again to a previously-allocated-and-initialized myView will break this assumption, causing memory leaks and possibly subsequent weird behavior. Both result from your second init message to myView creating objects, adding observers, etc. that the same object had already set up before.

That's what the second line in someMethod does.

The first line creates a new view, this being the impact of the alloc/init one-two punch. This view is a different object from the view you entered someMethod with (if any), so sending init to that object as part of its creation is not a problem.

Remember: the object is not the variable. myView is the name of the variable; when we say “myView”, we really mean “the object that myView holds”.

(It may be a good idea to re-read this answer from the top with the concept from the last paragraph firmly in mind.)

OTHER TIPS

This statement myView = [[NSView alloc] init]; is just a nested method call to this following

NSView *myView =[NSView alloc]; //line 1
myView=[myView init];//line 2

If you do it in a single line or in multiple lines it doesn't do any thing specific.

line 1 : here a new memory location is allocated for the object.

line 2 : An init is sent to the object, to initialize the object.

Objective-C differs from many other object-oriented languages in making object creation an explicit two stage process, allocation and initialisation.

If you are familiar with languages such as Java, C# and C++ then the allocation part of object creation is indivisible from initialisation. So for example in Java you might write:

class Tree {

// constructor/initialiser
public Tree ()
{
   // whatever is needed to initialise a Tree
}

}

...
Tree myTree = new Tree(); // allocate and initalise a tree

Java's new expression allocates memory for a Tree and then invokes the constructor to setup up that memory correctly.

The above languages are recognising that allocation and initialisation are just two parts of what is really a single operation: object creation.

In Objective-C the above example would be:

@implementation Tree

// constructor/initialiser
(id) init ()
{
   // whatever is needed to initialise a Tree
}

@end

...
Tree *myTree = [[Tree alloc] init]; // allocate and initalise a tree

Here you could in theory separate the allocation and the initialization but that is not to be advised. The reason for this is [Tree alloc] doesn't usually return a fully formed Tree, it allocates some memory and marks it as a Tree but any instance variables owned by Tree, or the super classes of Tree are not initialised - to do the initialisation init must be called. If you separate the two operations then you potentially have incomplete objects lying around which will not behave as expected. So though you can separate them doing so is so unwise that Apple's documentation for init states:

An init message is coupled with an alloc message in the same line of code

That is Apple tells a small untruth to prevent you making a big mistake.

Objective-C does also provide a single operation form of creation:

Tree *myTree = [Tree new]; // alloc + init

However unlike Java et al if you write an initializer which takes arguments you don't get automatically get a version of new which takes arguments - you need to write that yourself (as a class method using alloc and the initializer which takes the arguments).

HTH

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top