when i create a new view based application a few methods in the implementation file (.h)
i do not understand their purpose and when i look into the developer center its kind of hard to understand because of how its explained.
what purpose do these methods have and what are they used for in plain english.
- (void)loadView
- (void)viewDidLoad
- (void)viewDidUnload
what im guessing the viewdidload is , is that when the view is loaded and anything between the braskets are executed first, but when there are other custom methods created (if that is the purpose of viewdidload) how does it know which method to execute? is the code executed from top to bottom? being that whatever method is listed first is executed?
also i have noticed the word super inside brackets along with other keywords. what is the purpose of super?
thank you!
Well, "super" means Super Class, or the parent class that your current class extends.
#interface MyViewController : UIViewController{}
In the code above, that you can find in some .h files, MyViewController extends UIViewController. So, all the time that you call "super" inside MyViewController, you are calling the UIViewController.
So, when you see the following structure, inside MyViewController...
- (void)viewDidLoad {
[super viewDidLoad];
.
.
.
.
.
}
... it means that when the method "viewDidLoad" is called, it will first call the method from it's super class, to after run it's own code.
if you let the whole viewDidLoad method commented, it means that the parent method will be called automatically, because you are not overwriting it like on the previous example.
To understand what all the methods (loadView, viewDidLoad, viewDidUnload), take a look at the UIViewController Class reference on Apple Developer Connection.
Cheers,
VFN
Your class is a derivative of the system class UIViewController (is a subclass, in Objective C lingo). [super someMethod] means - call this method for the base class (superclass in ObjC lingo).
If you're familiar with C#, super in ObjC means same as base in C#. And the same as super in Java. :)
The system-provided UIViewController class has loading functionality in its loadView method. This method is called by the system, and it does a lot of work. The viewDidLoad method, on the other hand, is defined in the base class but does not do much. Its purpose is that you can override it and provide your own functionality there. Same for viewDidUnload.
Related
Let's say I have a storyboard scene that has a UIViewController in it with its custom class set to ParentViewController. I'd like to create a ChildViewController that does almost everything the same as ParentViewController but customizes just a few behaviors. ParentViewController's init loads the scene from the storyboard.
What I have now is ChildViewController subclassing ParentViewController. When ChildViewController's init calls ParentViewController's init through [super init], the ParentViewController loads the scene which in turn makes my class a ParentViewController even though it was a ChildViewController. After that the ParentViewController's methods get called.
I can get around that by using a strategy pattern, giving the view controller objects that customize the behavior as needed. But the code I'm working in also keys off of the Class types, so I really need a ChildViewController to stay a ChildViewController, or logic down the line does the wrong thing.
Question 1: In this case is it safe to use object_setClass to set the class back to what it was?
Question 2: If I do that do I not need the strategy any more? I assume once the class is set back the proper subclass methods will be called.
I'm just concerned that changing the class when the framework changed it for me in the first place might break something else.
In the Master-Detail Xcode template, where do I define a function such that it is globally accessible (by all UIViewControllers and their subclasses)?
One possibility: You can define a category on an UIViewController with the method. So any UIViewController now has this method too.
Another possibility: subclass a UIViewController and write you method there. And then subclass from this custom viewcontroller.
Edit:
Also, my MasterViewController is a subclass of the UITableViewController while the DetailViewController is a subclass of UIViewController. If I subclass them both to a custom UIViewController, the MasterViewController will lose its UITableViewController inheritance
You could subclass a UITableViewController and do the same thing as with the UIViewController and subclass from this.
The basic idea is to have a UITableViewController and a UIViewController as template.
You can create methods in the appDelegate class that you can access through all your app. For example, in your AppDelegate.h you have declared this method as follow:
-(void)myMethod;
In your AppDelegate.m, you define it as:
-(void)myMethod
{
NSLog(#"myMethod is getting called");
}
From any other classes (Master or Detail, etc.), you access myMethod by:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate myMethod];
make the class and the methods static. use the plus instead of minus e.g. +(void)methodName:param(ParamType *); .
Note, you can't instantiate a object of this class. It is like procedural programming. I usually use if I need the same but changing value in different objects and views. I don't a better way it works for me, though.
If you have some code that doesn't care what class of object calls it, it could probably be encapsulated into a function or subroutine instead of a method.
A method is a special type of function or subroutine that knows about an object and its class. A function or subroutine is like a global method that doesn't.
Added:
Objective C is a superset of the C programming language. So C functions and subroutines are the same in both languages. You can write one in a (or any) .c or .m file, and declare it in a .h file to be included wherever you want it used. Pass it parameters as needed and get a return value from functions, just like methods (except for being unrelated to any inherent class of object).
Added #2: But since you want your method to know about some NSStreams, then it should probably be a method of some Model class (MVC paradigm) containing those streams, and not truly global. Pass this Model object to any view controllers or other classes that need to access it.
If i implement my own version of awakeFromNib, should I call [super awakeFromNib] at the end of my method?
awakeFromNib for UIKit (iOS):
You must call the super implementation of awakeFromNib to give parent classes the opportunity to perform any additional initialization they require. Although the default implementation of this method does nothing, many UIKit classes provide non-empty implementations. You may call the super implementation at any point during your own awakeFromNib method.
awakeFromNib for AppKit (Mac):
(not true anymore, if using OS X 10.6 or higher)
You should call the super implementation of awakeFromNib only if you know for certain that your superclass provides an implementation. Because the Application Kit does not provide a default implementation of the awakeFromNib method, calling super results in an exception if the parent class does not implement it. Classes whose immediate parent class is NSObject or NSView do not need to call the super implementation. For any other classes, you can use the instancesRespondToSelector: class method of NSObject to determine if the parent class responds to awakeFromNib and call the method if it does.
The documentation covers that perfectly.
If you meant to ask about Cocoa Touch, you're not so lucky: The UIKit documentation doesn't answer the question definitively anywhere that I could find. Best I can suggest would be to follow the same rules as in Cocoa.
Yes you should.
I implemented drag and drop and everything was working until I added my own awakeFromNib then the drag and drop function whichTypeToProcess never got called.
It wasn't till I added [super awakeFromNib]; as the last statement in my own awakeFromNib that the drag and drop function whichTypeToProcess was being called again and drag and drop started working again.
FYI - This was in a MacOSX application.
In Xcode, a lot of the auto-generated class files (especially those for UIViewController subclasses) will include methods that resemble the following:
- (void)dealloc {
[super dealloc]
}
To me, this seems fairly pointless - if all a method is going to do is call super, why have it at all? Is there a purpose to these methods being generated?
The default template code defines methods that are meant to be filled out with your customized code. The calls to super are there to remind you to make the call. The generated code is not meant to be a finished application. Think of the call to super as similar to the empty class definitions. You fill out the classes and therefore fill out the methods definitions
In Objective-C, how do you rewire a class's instance method to call a method in another class?
Say a UIView class A contains another UIView class called childA. I want it so that when childA's drawRect is called, a method in class A is invoked without having to subclass childA and do the desired call in its drawRect there. How can this be achieved?
Also, how do I supply a method to childA's draw class dynamically? I know this is probably not a good practice but it would be useful for testing purposes.
To answer your first question about rewiring methods:
You don't want to be doing this on general principle, since it kinda defeats the whole purpose of object-oriented design, but for testing purposes, it can be useful. As long as you're on Leopard, it's not especially difficult, either.
Take a look at the Objective-C 2.0 Runtime Reference, which contains the keys to the kingdom, as it were. Look at the functions class_getInstanceMethod, method_getImplementation, method_getTypeEncoding, and class_addMethod which, in combination, let you change the methods of a class at runtime.
If you're just swizzling one selector for another, method_exchangeImplementations is a useful shortcut.
To answer your second question about supplying a method dynamically, that's as simple as passing a SEL to a method and then calling -performSelector:withObject::
#interface MyView : NSView {
SEL drawingSelector;
id drawingDelegate;
}
#property SEL drawingSelector;
#property id drawingDelegate;
#end
#implementation MyView
- (void)drawRect:(NSRect)rect {
[self.drawingDelegate performSelector:drawingSelector withObject:[NSValue valueWithRect:rect]];
}
#end
For the first issue you raise, it seems like you would set up UIView A as a delegate object of childA and the other UIViews - then they could use delegate methods to call the extra drawing features you wanted in A.
Either that or have each child ask for the superview and if it is of type "A" call the method you are interested in.