I see some example code with [super viewDidLoad] called before your implementation and after your implementation.
I know you don't always have to call super (as seen in many other discussions).
When you do call it, is it expected before or after you code?
This could have consequences depending on what super's implementation does. Though you shouldn't have to know super's implementation to write yours.
Of course this goes for all of UIViewControllers delegate methods (willAppear, didAppear, etc...)
Any thoughts?
My rule of thumb is: if you're doing something related to initialization, always call the super class's method first (if you are going to call it at all). This gives the super class a chance to do any set-up that you may be relying on later in your method. If you're doing something related to destruction, call the super class's method last. This makes sure that you can rely on the state of the object throughout the execution of your method. Finally, take any other case on a case-by-case basis. For instance, if you're handling an event, you probably want to deal with the event first, and only invoke the super class's method if you chose not to handle the event or if you somehow altered it and want to pass it along the event chain.
Lets say you have 2 class, a Parent and a Child. Child inherits from Parent. They have a method called greet which returns a string.
Here is what the parent method looks like:
Code:
-(NSString *)greet {
return #"Hello";
}
We want the child to learn from his parents. So we use super to say greet how Mommy would greet, but with our own little additions too.
Code: // Inherits from Parent
-(NSString *)greet {
NSString *parentGreeting = [super greet];
return [parentGreeting stringByAppendingString:#", Mommy"]
}
So now Parent greets "Hello", and the Child greets "Hello, Mommy". Later on, if we change the parent's greet to return just "Hi", then both classes will be affected and you will have "Hi" and "Hi, Mommy".
super is used to call a method as defined by a superclass. It is used to access methods that have been overriden by subclasses so that the class can wrap its own code around a method that it's parent class implements. It's very handy if you are doing any sort of inheritance at all.
Related
I have some class SimpleButton. It is a Child of Button class. Button class has some method, which is overridden in SimpleButton. Now, if I whant to get access to this method from simpleButton, I just need to call [super someMethod]; But how to get access to it from outside of simpleButton? I tried:
SimpleButton *button;
[(Button*)button.superclass someMethod];
but this does not works...
You can't do it like that. If you've overridden a method in a subclass then you have changed the publicly available method of that class to be the one in your implementation. You would have to have a separate method which just calls the super implementation:
Say you've overridden method foo. Create a new method, superFoo
[button superFoo];
Which internally does this:
-(void)superFoo
{
[super foo];
}
However, if you need to do this sort of thing then you probably need to rethink why you have overridden the method in the first place. Perhaps you should have a new method on your subclass instead which does the unique parts and calls the super implementation itself, rather than overriding.
I'm able to make the method for the call [self weaponAttachments:mpk5] but I don't like having to call self. I think [mpk5 weaponAttachments] is more natural and is easier to read.
The problem I'm having is I need to pass in the weapon (mpk5) in order to use it, which I can do with the first method but not with the second one. Does this mean that I need to subclass NSDictionary in order to be able to use a statement like [mpk5 weaponAttachments]? If so, how do I get ahold of the caller "mpk5" so that I can use it inside the method?
EDIT
I apologize for not putting this in the first time but my objective is to have [mpk5 weaponAttachments] return an NSDictionary or NSArray. Right now I have NSDictionary *attachments = [self weaponAttachments:mpk5]; which works but it just doesn't seem like the best approach.
So firstly, your two calls are a little mixed up:
[self weaponAttachments:mpk5] calls the weaponAttachments method, passing in the variable mpk5.
But [mpk5 weaponAttachments] is either asking the mpk5 object to return the weaponAttachments property or is asking the mpk5 object to run a method called weaponAttachments (I'm simplifying here - it's always a method, but if you're using properties you probably won't realise this as Objective-C will create them for you).
These are fundamentally different things.
On to the brunt of your question:
I don't like having to call self
...unfortunately, if you're working in an object-oriented language you're going to have to get used to this. Say I have a class called mySimpleClass, and a method inside that class called doSomething. Writing this:
[mySimpleClass doSomething] would be what we call a static method. Whereas calling [self doSomething] from within an instance of mySimpleClass would be an instance method.
If you're unsure of the difference between static and instance methods you should probably step back and take a look at some of the basic guides out there.
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
-(void)viewWillAppear:(BOOL)animated{
//something here
[super viewWillAppear];
}
Is [super viewWillAppear]; always required? If not when and why do you use it?
First of all, the correct boiler plate should be:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//something here
}
In other words, call super first, then do your own thing. And you have to pass the animated parameter to super.
You usually want to call the super class' implementation first in any method. In many languages it's required. In Objective-C it's not, but you can easily run into trouble if you don't put it at the top of your method. (That said, I sometimes break this pattern.)
Is calling super's implementation required? In the case of this particular method you could get unexpected behavior if you don't call it (especially if you have subclassed a UINavigationController for example). So the answer is no not in a technical sense, but you should probably always do it.
However, in many other methods there may be good reasons for not calling super.
Calling super method provide possibility to execute code in parent class.
Regarding your question according to Apple doc
So, yes, this method required.
In my experience, calling [super viewWillAppear] in the first line, when calling reloadData after that, makes it impossible to retrieve the previously selected row when coming back from a detail view. When [super viewWillAppear] is the last sentence, you can get the selected row and show the previously selected row hint. This happens only when using [tableView reloadData] inside viewWillAppear.
Lets say you have 2 class, a Parent and a Child. Child inherits from Parent. They have a method called greet which returns a string.
Here is what the parent method looks like:
Code:
-(NSString *)greet {
return #"Hello";
}
We want the child to learn from his parents. So we use super to say greet how Mommy would greet, but with our own little additions too.
Code:
// Inherits from Parent
-(NSString *)greet {
NSString *parentGreeting = [super greet];
return [parentGreeting stringByAppendingString:#", Mommy"]
}
So now Parent greets "Hello", and the Child greets "Hello, Mommy". Later on, if we change the parent's greet to return just "Hi", then both classes will be affected and you will have "Hi" and "Hi, Mommy".
super is used to call a method as defined by a superclass. It is used to access methods that have been overriden by subclasses so that the class can wrap its own code around a method that it's parent class implements. It's very handy if you are doing any sort of inheritance at all.
I am writing an iPhone application which in numerous places needs to perform non HTTP or FTP networking of a very simple request response type.
I've wrapped all this up into a SimpleQuery class that integrates with the run loop.
SimpleQuery *lookup = [[SimpleQuery alloc] init];
[lookup setDelegate:self];
[lookup doQueryToHost:queryServer port:queryPort query:queryString ];
As you can see the calling object sets itself as a delegate. When the results are complete it then calls a method on the delegate with the results.
[delegate simpleQueryResult:resultString simpleQuery:self];
I am now in a position where I have a user of SimpleQuery that has two types of query so I need to extend SimpleQuery to support this.
I can think of two sensible ways of doing this.
Firstly passing a selector into doQueryString, or a seperate doQueryStringWithSelector.
[lookup doQueryToHost:queryServer port:queryPort query:queryString selector:#SEL ];
Secondly passing a tag into doQueryString so that when the delegate is called it can query the tag, as the simpleQuery is passed, to find out what the results are for.
[lookup doQueryToHost:queryServer port:queryPort query:queryString withTag:tag ];
I'm just wondering which is best from a coding style perspective, the first seems simpler but tagging seems more in keeping with the iPhone SDK and Interface Builder
An option which is used commonly in Apple's code (for example, in UIControl) is to provide both a target object and a selector. This works only if there is a single callback, and is more appropriate than a delegate in that case. (If there are multiple callbacks, then you'll probably have to go with a delegate and the tag approach.)
If you go this route, then you do away with the delegate altogether and instead have a method with a signature like this:
doQueryToHost:(id)queryServer port:(int)queryPort query:(NSString*)queryString target:(id)target action:(SEL)action
Note that "action" is typically preferred over "selector" in methods arguments in this case. The query would simply call the selector on the target when done. This would allow your clients to have multiple selectors, and also multiple target objects; this can help clean up code because you don't need to shove everything into a single delegate object.
If you want to go with your tag route, you should call it "context", which is what Apple uses (for example, in addObserver:forKeyPath:options:context).
There's a third option that's a common pattern in the kits, which is to use #protocols.
For example:
#protocol QueryCompleteHandlerProtocol
- (void)queryType1Complete:(int)intStuff;
- (void)queryType2Complete:(float)floatStuff;
#end
What this does is declare a set of method calls that an object adopting the protocol has to conform to (the compiler will actually enforce this).
So your SimpleQuery object will hold on to something like the delegate pointer, which you might declare like this among the ivars:
NSObject<QueryCompleteHandlerProtocol> *callback;
What this tells the compiler is that callback is an object that descends from NSObject and adopts the QueryCompleteHandlerProtocol protocol. Sometimes you see this written as:
id<QueryCompleteHandlerProtocol> callback;
When you want to call the callback there's nothing special about them, SimpleQuery's methods will just call:
[callback queryType1Complete:1];
[callback queryType2Complete:2.0];
Finally you client for the procotol class will declare itself as adopting the protocol:
#interface MyClass : NSObject<QueryCompleteHandlerProtocol>
...
#end
And will set itself as the callback with some code like:
[lookup setCallback:self];
This is where the compiler checks that MyClass conforms to QueryCompleteHandlerProtocol, meaning it has implemented queryType1Complete: and queryType2Complete:.
I'm not sure I understand the problem here. Can't SimpleQuery's user just set another delegate object for the second query, or branch on the simpleQuery: parameter? That's a basic part of the delegate pattern, just like having two UIActionSheets for one view controller.