Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Dylan Aresu
9,687 Pointscould someone help me understand this -(instancetype)init method ???
Right i'm doing ios objective c and we've came across this piece of code, could someone please explain why we use -(instancetype) for the type first of all, why we are initalising super and assigning it to self, and why on earth we check for self? How is self going to be a bool value? self is simply the class in which this piece of code lies within isn't it?
-(instancetype)init { self = [super init]; if(self) { }
return self; }
Cheers... i'm a noobie in ios so would be great for someone to explain in it extremely simple terms.
4 Answers
Jesse Ditson
6,066 PointsHere's what's happening in this snippet:
we use instancetype instead of id here, because we want to return the type of super, instead of an id.
It is functionally identical to returning the type of this class.
- (instancetype) init {
here we call our superclass, therefore making this instance a subclass. We're only allowed to assign to self inside of init, but this is how we inherit from a superclass in objective-c.
- note that before we call this, self is nil (it is just an allocated piece of memory).
self = [super init];
this if check isn't checking for a bool, it's checking for nil (which is falsy in objective c). If our superclass returned nil from init (which is possible since any method may return nil on objective-c), this block will be skipped.
if (self) {
// this is where we would do things that are specific to our class.
// If our superclass failed to init, we don't want to attempt operations on self, as it would be nil.
}
finally, return self. If we don't return self, we'll implicitly return nil,
which would mean calling [[MyClass alloc] init] would return nil, instead of an instance of MyClass.
return self;
}
Damien Watson
27,419 PointsJesse has already answered this, but I took a while to type out. :)
I have used the code in question in the following way 'NSObject' is one of many classes, I just used this as an example:
@interface exampleCategory : NSObject
@end
-(instancetype)init {
self = [super init];
if (self) {
}
return self;
}
'instancetype' is used to return a class of the same type (in this case 'NSObject').
As we are subClassing the 'NSObject' class, we pull the 'init' method from the parent definition (superClass) to use in our own definition (self).
When you check 'if(self)', it returns 'false' if not defined and 'true' if defined. This is the same in most languages I have come across. It doesn't have to be a boolean to return these. It's saying 'if self exists', which returns true/false.
I hope this helps. Cheers.
Dylan Aresu
9,687 PointsThank you, i sort of understand now.
ARMANDO RODRIGUEZ
4,216 PointsDon't look at the code and instead think of it this way:
Let's say "init" is a way of saying, you create a sandwich.
When you "init" a sandwich, it has the properties meat, bread, veggies and cheese but those properties aren't specific for turkey or roast beef or vegan or whatever. So when you "init", you just get a very basic sandwich.
But now let's say you want to make a "turkey swiss" sandwich. This turkey swiss has the same "class" sandwich, but meat is always turkey and cheese is always swiss.
If you simply do "init", you'll get a regular sandwich, called a "turkey swiss", but it can have cheddar cheese and ham, and we don't want that. Every time we "init" that turkey sandwich, we have to give it turkey and swiss and if anyone tries to simply "init" it, they should always get turkey and swiss.
So when you init the turkey sandwich, you ask, "is this the turkey sandwich? if it is, give it turkey and swiss, immediately and don't return it until you do."
self = [super init];
This line says "I will become a turkey sandwich." Programmatically, the line is the same as
Sandwich *sandwich = [Sandwich alloc] init];
But we are taking OVER that method, because in actuality, if we're calling this on a custom sandwich, it'll be [[TurkeySandwich alloc] init] and we need to make sure the REGULAR sandwich init method doesn't complete.
So that's why in the next line...
if (self)
This line says "If I am a turkey sandwich, then..."
if (self) {
self.meat = @"turkey";
self.cheese = @"swiss";
}
"I will have turkey and swiss for my meat and cheese."
And this line...
return self;
Says "Now that I am a complete turkey sandwich, here I am".