The standard NSView initializer initWithFrame:(NSRect)frame; is not getting called in my custom view. I've tried simple init, but so far, nothing is called. Also, the drawRect: method is not called. So how is one to intercept the initialization of the AVPlayerView?
I found the answer to this (using Objective-C) - it is:
(instancetype) initWithCoder:(NSCoder *)coder;
Related
Background - in my iPhone app I have a custom UITableViewController - I was going to pass some required config to it by extending the existing "(id)initWithStyle:(UITableViewStyle)style" method to an extended custom one.
Question - what's the best way to ensure that the user of this custom controller class can only call my custom init method, and not initWithStyle or any other init methods?
I usually document this and put a [self doesNotRecognizeSelector:_cmd] call into the init methods that are not intended to be used.
In conjunction, marking the method deprecated (see How do I flag a function as being deprecated in an iPhone Objective C header file?) prevents runtime suprises and gets you a warning at compile time.
You can override the init methods that you don't want to be used, and raise an exception there.
You can also override them and make them initialize with the designated initializer.
Also, you should specify it on your documentation.
-(void)viewwillAppear
{
[super viewwillAppear:animated];
}
What does mean of calling [super viewwillAppear:animated] and what happen if we not call it?
By using super you are calling the base class version of the method. You will see similar call in init, dealloc, viewDidLoad etc. methods. The reason is in base class's implementation something important may be carried out without which the derived class will not work properly. When you have overridden the method in derived class, you will need to make a call to the base version by using super.
The only situation you will not call base class's method by using super is when you know that you don't need the tasks carried out by base class, in other words you are overriding completely. This is not the situation with viewWillAppear:animated or viewDidLoad etc. So we always call super in these cases.
Apple's documentation for viewWillAppear: just says:
If you override this method, you must call super at some point in your implementation.
It will probably lead to some unexpected behavior if you don't call it. Note that 'at some point' means you don't have to call it first.
The reference clearly states
This method is called before the
receiver’s view is about to be
displayed onscreen and before any
animations are configured for showing
the view. You can override this method
to perform custom tasks associated
with presenting the view. For example,
you might use this method to change
the orientation or style of the status
bar to coordinate with the orientation
or style of the view being presented.
If you override this method, you must
call super at some point in your
implementation.
In viewDidLoad do you put [super viewDidLoad] before or after your code? Is it the same for all other methods?
Before. You want the super initialization to happen before yours, so that your code could rely on the super state.
As for the other methods - it depends whether you want your code to touch the parameters before calling the super method or it needs to process the result of it.
When creating a UIViewController derived class in objective-C, what goes into the init method, what should go into loadView and what into viewDidLoad - and more importantly why, and what benefit (performance?) does this have?
Also, how does this relate to UIView derived classes where the only option you have is the init method?
I know the template code already has comments for what goes into each method, but it unclear to me why each thing goes where they say.
Clarification
I would like to know maybe at a lower level, what is the actual difference between things being done in the 'init', 'loadView' and 'viewDidLoad'. What does the framework do in between these calls that may affect the way/time I set up my views and do other work? How are these methods affected by threading?
You want to know some lower-level stuff.
init: This method gets called on ANY NSObject subclass. It is what sets up the object, which you probably already know. In many model (as in the MVC pattern) classes, init is directly used. As for the UIKit classes, very few requires init to be called directly. It should not be used. In the UIViewController, you initialize it using initWithNibNamed:. You can override this method, but in most cases this is not needed. This method is the VERY first method to EVER get called on the class (before any view setup, or such).
loadView:and viewDidLoad: read this article iPhone SDK: what is the difference between loadView and viewDidLoad? .
The only really important thing to know is that -init is the NSObject standard initialization method. -loadView and -viewDidLoad are UIViewController's methods for initialization.
In this code I am loading a View Controller (and associated View) from a .xib:
-(id)initWithCoder:(NSCoder *)coder
{
// add custom initialisation code here
[super initWithCoder:coder];
return self;
}
This successfully works, but I do not really understand what the line [super initWithCoder:coder] is accomplishing. Is that initializing my View Controller after my View has been initialized?
Please be as explicit as possible when explaining. Thanks.
Your class is a subclass of UIViewController. The call is telling your super class (UIViewController) to do the steps it needs to accomplish so that you can do your init steps. This would be setting up any properties that the UIViewController provides or registering for notifications that the UIViewController needs to do its work.
It is suggested almost every time you override a method from the super class to call the super class's method in addition to the steps you need to take.
Edit: Also if you don't need to do anything in a method the superclass provides, you can just leave it out and the super class's method will be used instead. In this case I would not provide the initWithCoder: method unless there was some code you need to preform in addition to what you showed.