Few questions about overriding the init function - iphone

As an Objective-C beginner, I'm very confused about the init function, and how and when to override it. So here are few questions :
Apparently, it works fine when the init function is not overridden, so is it just a good practice to do it? If it is, then is it a very bad practice not to do it?
Let's assume I'm overriding the function because I have to assign a default value to a variable. Do I have to allocate and initialize all the other ivars, including IBOutlets?
Please note I'm aware of the syntax :
if ((self = [super init]))
{
_foo = [[Bar alloc] init];
}
return self;

Per "Initialization":
A class generally implements an initializer for its objects, but is not required to. If a class does not implement an initializer, Cocoa calls the initializer of the nearest ancestor of the class. However, subclasses often define their own initializer or override an initializer of their superclass to add class-specific initializations. If a class does implement an initializer, it should invoke an initializer of its superclass as the first step. This requirement ensures a series of initializations for an object down the inheritance chain, starting with the root object. The NSObject class declares the init method as the default object initializer, so it is always invoked last but returns first.
As this says, you override your superclass's designated initializer when you need to do some initialization after it's done with its initialization. Don't need to do that? Then you don't need to override.
When your object is instantiated from a NIB, -init is not called. Instead, your newly allocated object will receive an -initWithCoder: or -initWithFrame: message depending on the object's type. The NIB loading process sends your object -awakeFromNib after it and all the other NIB-created objects it references have been established. This lets you avoid overriding -initWithCoder:/-initWithFrame: when you wish to do some configuration after the NIB has been loaded. If you can do what you want to do by overriding -awakeFromNib rather than an initializer, you should do that.
See also "Multiple Initializers", which explains the "designated initializer" concept and how different classes can have different designated initializers, and "Allocating and Initializing Objects" for a less friendly but more in-depth description of the allocation and initialization conventions adopted by Objective-C.

There is no need to override -init (or the designated initializer) unless you need to do class-specific initialization.
You do not need to (nor should you) allocate or initizlize IBOutlets. Objective-C will automatically initialize all instance variables including IBOutlets to 0 (nil).

no not at all .... just initialize what ever you want ... again IBOutlets are not initialized ... you only set them to nil when there is a memory warning or when ever you want to break the link ....

Related

In Swift, why do subclass designated initializers follow this order?

I'm trying to understand how the compiler works around this.
I've read that subclass designated initializers must:
First initialize all properties of the subclass.
Then call super.init().
I don't understand why the subclass must initialise first and the initialise the superclass. How is this possible if the superclass doesn't exist yet?
Thanks!
On https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID215 under "Two-Phase Initialization", it is explained extensively
The main reason is safety. Each property must first assign a value -- and then only when the entire hierarchy has done that, can you start reading values.
The reason super.init() comes after subclass property initialization is so that super.init() can call a method that might be overridden in your class. When it does that, we know that you have already given your properties an initial value.

Why not use self. call inside class

I've read google's and apple's code guide, they both access instance variables without self. call(getter and setter) inside the method implementation even though they have declared a property for that instance variable.That's why?
In my opinion, using self. call to set and get instance variables inside the method implementation of class makes it easier to manager retain count.
Is there any caveat to use getter and setter inside class?
It depends. You should always use the accessor in normal use.
However for init and dealloc methods, you should instead use the direct ivars to release and set variables. That's because the setters can have side effects that are not good to trigger during class initialization or deallocation.
In practice using an accessor as part of init probably will not cause an issue. But I have seen a number of real world crashes where a custom setter was not expecting nil and so use of the accessor in dealloc crashed the app. Even if it didn't crash it could be doing a lot of pointless work since the class was about to die.

Significance of Super?

Can anybody tell me why we need the super in every method for e.g.:
-(void)viewDidLoad
{
[super viewDidLoad];
}
I am confused about the super keyword....
[super ...] calls the implementation of the method in your class's superclass. It is important to use if the inheriting class wants to extend the method implementation (i.e., add something to it but also do what the superclass did) as opposed to replacing the method implementation.
As such, you do not call super in every method you override but only where it is appropriate. If you should, must or must not call super in a specific method should be mentioned in the documentation of that method.
To call the method of the parent class.
This is the rule when you override the method of the superclass, so that you can make sure that code in the superclass get executed and behave correctly.
Note: Sometimes, you call super in the beginning of the method, some other times, in the end of the method

Assigning ivars using self keyword in an object's init method

I've read that it's bad to use self.ivar = (convenience method) in and object's 'init' method, as this messes with inheritance.
However, if you know you're not going to subclass your object, is it ok to use the self keyword assignment?
i.e. self.iVar = [Object objectConvenienceMethod];
The reason I ask is this. I create a new object with its own init method, and in that method, I perform various initial assignments. Since I don't use the self keyword, I assign them directly to the iVars, and therefore use the alloc methods rather than the convenience methods. I.e.
iVar = [[Object alloc] init];
Or if I use a convenience method, I retain it. I.e.
iVar = [[Object convenienceMethod]retain]
But... when I run my program with the memory leak tool on, all of these assignments are identified as memory leaks.
If I can use the self keyword plus a convenience method instead of alloc-init, then this would avoid the problem.
If I choose to use the alloc-init approach though, where am I supposed to release the iVars?? Just in dealloc?
Thanks for your help :)
Michael
No, because it isn't only subclass behavior you need to take into account — superclass implementations and even the behavior of code generated by the framework (e.g. synthesized accessors and the black magic used to implement KVO) can also cause trouble. It will probably be OK, but that's still a significant chance of being not-OK. All in all, it's best just to follow Apple's recommendation and assign directly.
Assigning to ivars in init shouldn't be reported as leaks in a properly functioning program. If you're seeing that, there's some other problem that you need to address. Try reducing the problem to a minimal case that we can try out and ask about that — then we can tell what's wrong.
If you alloc or retain them in your class's init method, you should release them in the corresponding dealloc method.
I am thinking your "enclosing" class is not being released, and hence its dealloc method is not being called resulting in your iVars not being released.

Would it be correct/ellegant use only alloc without init?

If we don't want to implement init method in our class, and bearing in mind that init in NSObject only returns an instance of the object without initialization, I don't see the point of calling init if we already get the instance with alloc. I have tried and it works, but I am not sure it won't cause future problems.
myClass *newObject = [myClass alloc];
instead of:
myClass *newObject = [[myClass alloc] init];
Thanks a lot.
No, just calling alloc would not be correct. alloc zeroes out all instance variables of the object, init then has the chance to set all or some instance variables to their default values. Some classes even use their init methods to create another instance and return that one instead of the one you allocated.
Many classes expect that their init methods get called and would possibly cause crashes if you don't call init. If you are talking about a custom class that inherits directly from NSObject and needs no initialization of instance variables, you might get away with [myClass alloc] but it is definitely not good programming style.
I think that it is not a good idea.
Read Cocoa Design Pattern, especially the "Two stage creation"
You can also read this article http://www.informit.com/articles/article.aspx?p=1398610
I think that it wouldn't matter much if you didn't implement a "- (id)init" because if you did, you would call NSObject's init method which just returns the same value you send to the method. Though it is a good idea to create your own init method to set your instance variable.
in runtime source code
perform -(id)init will call _objc_rootInit(self) and will return self. I guess only perform init is OK。