I'm pretty new to Objective-C, so I am not entirely sure of the terms I should be searching for. Apologies if you've seen this question before.
I have noticed that in the skeleton projects that XCode produces contain overrides like so:
- (void)viewDidLoad
{
[super viewDidLoad];
}
I am not sure why this is part of the code that is generated. I am confident that I could omit this method and not affect the application because it simply calls the method on the parent class. Is this method stub just here to show the developer that they can override this commonly overridden method, or is this something in Objective-C that I have not yet come across?
It's a method that you'll often want to override, so it's included in the template as a convenience. If you don't add any code of your own to it, you could as well remove it altogether because only calling super is the same as leaving it out.
I suspect it's also included to remind you that you have to call super if you override it.
Yes, if you have nothing to add to this method it could be left out. It is there to provide you a template where you can add your code for things you want done in viewDidLoad.
Related
My NSDocument subclass implements selectAll:. Only problem is, I'm using NSTableView, and it also implements selectAll:. However, the selectAll: action in NSTableView doesn't do what I want, and it does prevent the selectAll: method in my Document class from ever being reached in the responder chain.
I already have a subclass of NSTableView, and after poking around a bit I got things working the way I want by adding a respondsToSelector: method to my NSTableView subclass which lies to the runtime by telling it there is no selectAll: action:
-(BOOL)respondsToSelector:(SEL)targetSelector
{
if (targetSelector == #selector(selectAll:)) {
return FALSE; // we don't want tableView's implementation of selectAll
}
return [super respondsToSelector:targetSelector];
}
This seems to work fine, allowing the selectAll: method in my document subclass to do its thing. But this solution leaves me a bit uneasy. What about other action methods I have implemented in this subclass? Do I need to manually check and return true for each of them? I do have two actions defined in this subclass, moveLeft: and moveRight:, and they seem to work, even though I am not handling them in respondsToSelector:. So my question is, am I doing this correctly, or is there something I am missing? Or perhaps there is some entirely different way to do this properly?
By the way, I got the idea of overriding respondsToSelector from this post on the OmniGroup forum:
http://mac-os-x.10953.n7.nabble.com/Removing-an-action-from-a-subclass-td27045.html
Sending a message to super affects which implementation of that method we use. It doesn't change who self is.
So let's try to imagine how respondsToSelector: works. Given a selector mySelector, it probably introspects every class up the superclass chain, starting with [self class], to see whether it actually implements mySelector.
Now then, let's say your subclass is called MyTableView. When MyTableView says
[super respondsToSelector:targetSelector]
what happens? The runtime will look up the superclass chain for another implementation of respondsToSelector:, and eventually will find NSObject's original implementation. What does that implementation do? Well, we just answered that: it starts the search for an implementation of targetSelector in [self class]. That's still the MyTableView class! So if you have defined moveLeft: in MyTableView, respondsToSelector: will find it and will return YES for moveLeft:, exactly as you hope and expect.
Thus, to generalize, the only selector for which this search has been perverted is the search for selectAll: - exactly as you hope and expect. So I think you can relax and believe that what you're doing is not only acceptable and workable but the normal solution to the problem you originally posed.
You might also like to look at the Message Forwarding chapter of Apple's Objective-C Runtime Programming Guide.
Apologies if this is duplicate. If so I am thankful for a link and happy to delete my question. However, I did not find an answer between tons of search results. This is not the usual case of unrecognized selectors. The selector is nil. And it is thrown on this very line:
return self.topViewController;
That line is embedded in:
#implementation UINavigationController (JTRevealSidebarV2)
- (UIViewController *)selectedViewController {
return self.topViewController;
}
#end
As you see it is an attempt to extend UINavigationController. You may have noticed that my code is based on this turorial:
https://github.com/mystcolor/JTRevealSidebarDemo
(Based on the Demo of Version 2, if anybody is interested).
As far as I have noticed I have not yet made any change to mystycolor's framework. Especially not UIViewController+JTRevealSidebarV2.h nor .m.
So far I only made changes to one of the two view controllers, that are presented. Those, that contain the contents, not the navigation logic.
Apparently the method is being called. Therefore the category must have been used in some correct way? And all what mystycolor is using there, he calls a well documented method and returns its value.
As it is from a tutorial, which is foreign code, do not ask me why topViewController is not called directly. I will try that next of course, but even if that helps I'd still be courius about what went wrong here.
Just out of curiosity I did change that expression to return [self topViewController];, but no surprise that did not make a change.
I am happy to provide more code but don't know which sniplet may be interesting for you to help.
This is not an answer to the question WHY but I found out what I made wrong.
One fo the view controllers I was working with did not include
#import "UIViewController+JTRevealSidebarV2.h"
#import "UINavigationItem+JTRevealSidebarV2.h"
The method selectedViewController is implemented for both categories but does different things when being called. That is the answer to the question why mystycolor did implement it that way.
And now that I added these includes it works fine.
But to me the error message is still confusing. How could it be that the method was called at all, when the reason for the error appears to be that the extension, of which the method is part of, was not included everywhere?
This is something I have been curious about:
If you create a new UIViewController subclass in Xcode, they stub in a few functions including ViewDidUnload. But there is no dealloc method.
Why wouldn't they stub that method into the class?
You can create your own templates for Xcode. If you want to add a dealloc method to your template, go for it.
Look in ~/Library/Application Support/Apple/Developer Tools/Templates/.
I think that's a reasonable question - it would seem including it would make sense, given there's a high liklihood that it would be used. But I suppose the only answer which is possible here, is that they decided not to (for whatever reason). You can of course add it yourself - and in iOS5 it may be fairly redundant with ARC.
In the function viewDidUnload it is initially empty. However, I'm following a tutorial where at the end of the function they write [super viewDidUnload]. I noticed that in the dealloc function, [super dealloc] is automatically written at the end. Why isn't it automatically written at the end of viewDidUnload? Does it make a difference? What does it do?
Also, is this a Cocoa question, or an Objective-C question?
This link may help: iPhone: [super viewDidUnload] calling order
Basically, if the superclass is just UIViewController, [UIViewController viewDidUnload] does nothing, so that's why it's not automatically added.
Call it at the end of the function.
I've had a lot of miscellaneous errors when i called at the beginning. I found a lot of places on the web discuss the topic, some say beginning, some say at the end. Before i researched, i figured it should be called at the end due to similar patterns of the structure and nature of the language (such as how touch events are handled).
My logic suggests that if i'm going to call the super, or parent of an object in question, i have to also think that the parent or super wouldn't know of the existence of the child object in its default implementation, and who knows what it might do. So when over-riding this method it would be logical to think that when setting outlets and properties to nil, that the super's unload method might do something like unload the view in a view controller while those outlets still exist.
Due to all the questions and answers i found, there is no clear cut solution. Apple doesn't give the immediate answer, but they provide an understanding of how the loading and unloading of views occurs. I quit looking for examples on this one and i'm sticking to the logic behind the call to super at the end of this function.
What i wouldn't do is assume I can guess what code is being run in private API's and that anyone other than an apple doc or an apple developer will have the right answer. nevertheless, this is my suggestion based on what i've experienced, perhaps the correct answer is that it should be either/or depending on what your doing in the method. Open to more suggestions.
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