31

Can someone explain to me what init and alloc do in Obj-C. I am reading this obj-c book that gives an example of creating object but it does not really go into details of what it does. What does alloc return? what does init return?

Animal * k = [Animal alloc];
k = [k init];
denniss
  • 17,229
  • 26
  • 92
  • 141

5 Answers5

52
  • alloc allocates a chunk of memory to hold the object, and returns the pointer.

    MyClass* myObj = [MyClass alloc];
    

    myObj cannot be used yet, because its internal state is not correctly setup. So, don't write a code like this.

  • init sets up the initial condition of the object and returns it. Note that what's returned by [a init] might be different from a. That explains the code Yannick wrote:

    -init{
         self=[super init]; // 1.
         if(self){          // 2.
             ....
         }
         return self;       // 3.
    }
    
    1. First, you need to call the superclass's init, to setup the superclass's instance variables, etc. That might return something not equal to the original self, so you need to assign what's returned to self.
    2. If self is non-nil, it means the part controlled by the superclass is correctly initialized. Now you perform your initialization. All of the instance variables are set to nil (if it's object) and 0 if it's integer. You'll need to perform additional initial settings.
    3. Return the set-up self. The returned self might be different from what's allocated! So, you need to assign the result of init to your variable.

This suggestions an important lesson: never split the call to alloc and init. Don't write:

 MyClass* myObj = [MyClass alloc];
 [myObj init];

because [myObj init] might return something else. Don't try to get around this by writing:

 MyClass* myObj = [MyClass alloc];
 myObj=[myObj init];

because you will eventually forget to write the part myObj= in the second line.

Always write:

 MyClass* myObj = [[MyClass alloc] init];

I also don't recommend writing:

 MyClass* myObj = [MyClass new];

because it does not correctly call the initialization method: some classes doesn't accept a plain init. For example, NSView needs initWithFrame:, which can't be called with new. So, don't use new either.

SmileBot
  • 19,393
  • 7
  • 65
  • 62
Yuji
  • 34,103
  • 3
  • 70
  • 88
  • 4
    that being said, if you don't need a custom `-init`, you can definitly call `+new`. If you look at the implementation of `+(id)new`, it's literally `return [[self alloc]init];` – Gil Sand Jul 29 '15 at 08:14
  • I have a question Yuji. The variable myObj is a pointer to the memory location right? Your point "First, you need to call the superclass's init, to setup the superclass's instance variables, etc. That might return something not equal to the original self", so do you mean in superclass a new object is allocated again because of which the pointer to memory location changes? – Pruthvidhar Rao Nadunooru Dec 14 '16 at 18:53
  • generally init is a method where members of the class are initialized, why the pointer changes is very weird! – Pruthvidhar Rao Nadunooru Dec 14 '16 at 19:09
  • @GilSand Old question I know but for new comers: using `alloc init` vs `new` is REALLY good practice. You'll never run into bugs by using `alloc init` by force of habit but you MAY run into bugs by having a habit of using `new`. – Jacksonkr Aug 19 '17 at 14:26
3

In its simplest form:

  • alloc: short for allocation, reservers a memory location and returns the pointer to that memory location. This pointer is then stored in the k variable.

  • init: short for initialization, sets up the object and returns the object. The init method depends on the object, but it generally involves sending the init message to the superclass. And if that init method (of the superclass) returns an object (not nil) some ivars may be set up depending on the task of that class.

--

Example of an init implementation, the Schedule class initializes its channels ivar with an empty array. Basically your giving the Schedule object a chance to sort itself out, so it can start receiving messages once it is created. You could remove the channels initialization from the init method, but then you would have to check if the channels ivar is nil in every method of the Schedule class and initialize it if it is indeed nil.

- (Schedule*)init {
  self = [super init];

  if (self) {
    channels = [[NSMutableArray alloc] initWithCapacity:0];
  }

  return self;
}
ynnckcmprnl
  • 4,382
  • 1
  • 24
  • 25
2

alloc and init are two methods that are inherited from NSObject you can provide your own methods or call the ones from NSObject

alloc allocates the memory to create a new instance of your class(@interface) init initializes the contents of that instance, by default init sets all member values to 0/nil however you can create your own init method to customize what is done.

Animal * k = [[Animal alloc] init]; // creates a new Animal object

you can also write

Animal * k = [Animal new]; // which would be a bit more similar to other languages
AndersK
  • 35,813
  • 6
  • 60
  • 86
0

The NSObject root class provides a class method, alloc, alloc: reservers a memory location and returns the pointer to that memory location.

The alloc method has one other important task, which is to clear out the memory allocated for the object’s properties by setting them to zero.

This avoids the usual problem of memory containing garbage from whatever was stored before, but is

not enough to initialize an object completely.

You need to combine a call to alloc with a call to init, another NSObject method:

  • (id)init; The init method is used by a class to make sure its properties have suitable initial values at creation. The correct way to allocate and initialize an object is to nest the alloc call inside the call to init, like this:

    ClassName *objectName = [ClassName alloc] init];

from: apple documents

iOS_Tejas
  • 209
  • 2
  • 9
-1

Alloc will allocate the memory for the object, but Init puts the object into the memory and sets the default values.