super viewDidUnload in Cocoa - objective-c

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.

Related

-[UINavigationController <null selector>]: unrecognized selector sent to instance

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?

Connecting actions works. Connecting outlets doesn't

I have a XIB file with my controls in it, loaded in the Interface Builder (Xcode 4.0.2 on Snow Leopard).
The file's owner is set to, let's say, the someClassController class, and I've also added (in the Interface Builder) an NSObject instance of someClass, as well.
I've managed to link e.g. a button with an action in someClassController or someClass - and it works for both of them.
However, whenever I link an outlet to ANY of them, it fails to show up; and NSLog reports NULL pointers.
Hint : My issue here could be much more complicated than it seems, since both my someClass and someClassController classes inherit other classes, which inherit other classes and so on (I'm dealing with a huge-to-chaotic codebase, and I don't really know what else could be helpful to post)... However, I would still like to hear your opinion on what might be going wrong in such a case...
When you see problems like this, it's almost always because you have more than one object of the kind that has the outlet. The one in the nib whose outlet you connected is not the one that is examining its outlet.
To investigate this, add statements in the object's initializer method(s) and possibly awakeFromNib to log the value of self.
Some (or all, or none) of the objects may be created in nibs, and some (or all, or none) of them may be created in code; objects in the latter group won't trip awakeFromNib, since they didn't.
Either way, once you've inventoried what instances of the class you have, you can kill them off until you're left with the ones you want.
To add to Peter Hosey's answer, and after reading some more details in the other question you posted about this issue, here are some other factors to consider:
The File Owner class selected in the nib is completely ignored at runtime. It's there only for design-time convenience – for checking available actions and outlets.
Is there any chance you're finding nil pointers in -init? Outlets are connected after -init and before -awakeFromNib. They'll never be connected in -init.
I'm trying to understand the sequence of initialization (from your other post). It sounds like you are creating a new instance of your CTTabContents subclass, and passing it to your CTBrowserWindowController subclass's -addTabContents: method. Then the CTBrowserWindowController loads your objects from the nib.
Or, maybe that's wrong. You might be creating a instance of your CTTabContentsController subclass. Then that object is loading TabContents.xib.
It's important to track down where the nib is being loaded and which object is being provided as the file owner at that time.
Another question: are you using manual release/retain, automatic reference counting, or garbage collection?
Finally, I reiterate the importance of printing out the self pointer in your initialization methods. In addition to -init and -awakeFromNib, try other initialization methods like your CTTabContents subclass' -initWithFrame:. When you're discovering intermittent null pointers in the rest of your debugging, print out the self pointers then, too. You'll probably be seeing different values of self then, too.

XCode skeleton projects overriding

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.

UITableView delegate method called twice

Today my question is about UITableViewController-s
In particular I have noticed that the datasource delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
is called twice (even if for instance I just create a navigation based application and without adding a line of code.. well adding an NSLog to track it).
Now, since in my application I need to determine the number of sections basing the choice on the documents in the file system, I need to call some methods to do so. I have put these methods in the above mentioned method, so they will be called twice, which is something I don't need.
The questions are why is it called twice, can I have it called once?
I hope that in the official documentation this is not clearly stated (which would mean that I didn't read it at all :) ). By the way I could see others posting similar questions, but I couldn't find a fully satisfying answer.
Thank you.
I was experiencing the same problem, only with the call to numberOfRowsInSection:
The answered laid in the stack trace for each call I received.
The first call was due to a change in the table header view I was making in the viewDidLoad: of my viewcontroller.
thumbView.tableHeaderView = nil;
thumbView.tableFooterView = nil;
This resulted in internal call to _updateContentSize: which called heightForTable: which eventually called numberOfRowsInSection:. This was something I triggered, and could be easily avoided by not doing the above code :)
The second call was the legitimate one in order to reloadData. This is triggered by a layout event somewhere and most likely you can't skip it.
I'm sure you can observe something similar for the numberOfSections: method
So, my conclusion is that due to the the implementation of UITableView there are many situations where certain delegate methods will get called twice or more because the table view has to refresh something. I try to design my code around this bug/feature/etc.
Hope it helps
If your tableview is contained by a child view controller,
Try this at your parent ViewController
[parentViewController addChildViewController:childViewController];
before [parentViewController.view addSubview:childViewController.view]
Please check your code, after adding TableView you may again called realodData method of table in mey be ViewWillAppear method
This can happen if you'r table view's frame gets changed by mistake in the story board.Say you clicked on the storyboard where you have added the table view as a subview and now your table may not be having the proper frame which you have set in the beginning.

Am I using NSTimer correctly in iPhone View-based app?

I'm working on a simple proof-of-concept for an iPhone app (and important bit of info, I'm pretty new to Mac OSX development all around). I created a view based app with a timer. I declared my NSTimer in the interface of my app's controller, used #property and #synthesize, and I initialize it in the controller's viewDidLoad method with scheduledTimerWithTimeInterval method. My selector is a method with the signature -(void)someMethod:(NSTimer *)timer which is declared in the interface and defined in the implementation file of the controller as well. I can step past the line where I assign the timer and see that it points to a valid object, but my program goes no further than the end of the viewDidLoad method and never reaches the breakpoint at the first line of my method that is called by the timer. Also, I see GDB: Program received bad signal: "EXC_BAD_ACCESS" in the status bar of xcode at this point (viewDidLoad end is reached). I didn't do anything in IB but add a view and a picker just so I'd see if the UI actually loads...it never does.
So, am I doing something wrong with the NSTimer, or are my troubles elsewhere? How can I use the debugging tools in xcode to get more information?
EXC_BAD_ACCESS usually indicates a memory management error, without seeing the code probably from somewhere else in your app. It's a very common error for beginners, but an important subject to fully understand, so I'd suggest looking through some of the questions on memory management here and find a few guides or tutorials to look through. It's actually pretty easy to learn.
Also, it shouldn't hurt but unless you need to access the timer in between fire events, you don't actually need to store it as an instance variable. Once you create and start a timer it's added to and retained by the application's run loop.
Have you got NSZombieEnabled?
Might be useful if this is failing on an over released object.