-(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.
Related
I'm looking to find out what the effects are (if any) of assigning a delegate multiple times? Is it bad practice to assign a delegate inside viewWillAppear considering I do not assign the delegate to another viewController?
It is just a simple custom delegate for one of my classes. I need the delegate in one view of my tabBar, but not in the other. And since I've been assigning it in viewWillAppear, and viewWillAppear gets called every time you change tabs, I was just wondering if there were some unwanted effects.
No, in the case you describe there should be no problem. But it depends on what your code does when the delegate is assigned. If it's a simple property assignment with no custom implementation of the 'setter' method for the property, then you have no issue. But if you wrote your own 'setter' method for the property and the implementation performs other actions, then it is possible that those other actions could be an issue.
Either way, you may wish to consider moving the assignment to the viewDidLoad method. As if iOS 6 this will only be called once. Under iOS 5 or earlier it could be called more than once but viewDidUnload will be called as well in such cases.
I'm still very new to Objective C, and I was wondering something regarding viewDidDisappear.
I have an app that plays a sound (using AVAudioPlayer), and I want to stop the sound when the view is switched.
If I do this in my view controller implementation:
- (void)viewDidDisappear:(BOOL)animated {
[self.audioPlayer stop];
}
it works fine. But the small programmer in my brain is saying that I'm not using this correctly.
I'm pretty sure you are supposed to CALL viewDidDisappear with a boolean argument, rather than just specify (BOOL)animated; besides, it would be nice to have some animation in my view switching... then again, that might be a whole different discussion!
So, what am I doing wrong, and how would I correctly use this? Do I have to link the call a button action? Where is the correct play to actually declare the function itself?
Thanks.
I implement viewDidDisappear:(BOOL)animated EXTENSIVELY, along with viewWillAppear, viewWillDisappear and viewWillDisappear The main reason to implement this method is to make your view controller to do something at the event, such as viewDidDisappear You don't call this method, but your app will call your view controller to do what's implemented there. Since this is inherited method, as long as you make sure all the inherited implementation from the super class can be done, it's great to implement viewDidDisappear. So, I suggest you to change your code to be like this:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:(BOOL)animated]; // Call the super class implementation.
// Usually calling super class implementation is done before self class implementation, but it's up to your application.
[self.audioPlayer stop];
}
- (void)viewDidDisappear:(BOOL)animated is a method declaration, not a call of any sort. The method itself is called by UIKit as view controllers are manipulated; you don't need to call it yourself unless you're writing your own code that makes view controllers appear and disappear by directly manipulating the views they control (e.g. if you were rewriting UINavigationController for some reason).
You are doing something wrong, though: you must call [super viewDidDisappear:animated] somewhere in your implementation, or things may break.
The "small programmer" voice in your mind is probably more used to procedural coding, where you call the OS and tell it what to do. Cocoa Touch instead uses an event driven paradigm, where your program has routines (methods) that the OS(framework)calls when it is good and ready. viewDidDisappear is one of those routines. Just sit tight, and wait for the OS to call it (assuming you've set everything up properly.)
viewDidDisappear: is an optional method that your view can utilize to execute custom code when the view does indeed disappear. You aren't required to have this in your view, and your code should (almost?) never need to call 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.
I have a UIView subclass that I manipulate a lot of graphics on based on touches. All the [self setNeedsDisplay] calls seem to be fine.
However, I used an instance variable pointer to my same UIView subclass instance, and then tried manipulating it and then calling [UIViewSubClass setNeedsDisplay] from another UIView class, and DrawRect is never being called. Are there restrictions to where you can call setNeedsDisplay from?
(This method is called when a button is clicked on another UIView subclass. The method is being called, but not DrawRect)
-(IBAction)loadGrid2;
{
tempSoundArray = musicGridView1.soundArray;
[musicGridView1.soundArray setButtonArrayToNull];
[musicGridView1 setNeedsDisplay];
musicGridView1.soundArray = tempSoundArray;
NSLog(#"loadGrid2 was called");
}
drawRect: will only be called when it makes sense; ie, the view must be visible, onscreen, and dirty. Is your drawRect: ever called? It should be called when the view is first brought onscreen as well.
To add to Ben:
This most likely means that you have problems elsewhere. Your pointer may not be nil or otherwise invalid or the view may not be added to the hierarchy properly.
You may want to consider not handling this type behavior within the view and instead in the view controller. Control behavior and save presentation state in the view controller and don't subclass the view classes. It will simplify your code with less "pointer passing". This will also make it easier to debug this type of problem.
If you feel your view controller is getting bloated, consider splitting the responsibilities up among multiple view controllers.
The question is all in the title. I want to execute some cleanup code when one view in my application gets unloaded. Is it possible to do so? If so, which is the event that I should intercept?
-viewDidUnload() or -viewWillDisappear() depending on your design. You probably want to go for viewDidUnload().
It will also depend on the sdk you are using. If you are using iphone-sdk 3.x then viewDidUnload will be called otherwise it will not get called. while viewWillDisappear is called in 2.x and above. Now still if you want to call a method only when the view is unloaded you can call it from the dealloc but it will not be highly trustable.
You'll want to take a look at viewDidUnload or viewWillDisappear, for cleanup you'll probably use viewDidUnload, you may also want to just do cleanup in the dealloc method.
From Apple's documentation:
viewDidUnload Called when the
controller’s view is released from
memory.
- (void)viewDidUnload
Discussion This method is called as a
counterpart to the viewDidLoad method.
It is called during low-memory
conditions when the view controller
needs to release its view and any
objects associated with that view to
free up memory. Because view
controllers often store references to
views and other view-related objects,
you should use this method to
relinquish ownership in those objects
so that the memory for them can be
reclaimed. You should do this only for
objects that you can easily recreate
later, either in your viewDidLoad
method or from other parts of your
application. You should not use this
method to release user data or any
other information that cannot be
easily recreated.
Typically, a view controller stores
references to objects using an outlet,
which is a variable or property that
includes the IBOutlet keyword and is
configured using Interface Builder. A
view controller may also store
pointers to objects that it creates
programmatically, such as in the
viewDidLoad method. The preferred way
to relinquish ownership of any object
(including those in outlets) is to use
the corresponding accessor method to
set the value of the object to nil.
However, if you do not have an
accessor method for a given object,
you may have to release the object
explicitly. For more information about
memory management practices, see
Memory Management Programming Guide
for Cocoa.
By the time this method is called, the
view property is nil.
Special Considerations If your view
controller stores references to views
and other custom objects, it is also
responsible for relinquishing
ownership of those objects safely in
its dealloc method. If you implement
this method but are building your
application for iPhone OS 2.x, your
dealloc method should release each
object but should also set the
reference to that object to nil before
calling super.
viewWillDisappear: Notifies the view
controller that its view is about to
be dismissed, covered, or otherwise
hidden from view.
- (void)viewWillDisappear:(BOOL)animated
Parameters animated If YES, the
disappearance of the view is being
animated.
Discussion This method is called in
response to a view being removed from
its window or covered by another view.
This method is called before the view
is actually removed or covered and
before any animations are configured.
Subclasses can override this method
and use it to commit editing changes,
resign the first responder status of
the view, or perform other relevant
tasks. For example, you might use this
method to revert changes to the
orientation or style of the status bar
that were made in the
viewDidDisappear: method when the view
was first presented. If you override
this method, you must call super at
some point in your implementation.