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?
Related
i have been working on moving one of my apps away from the "shared appdelegate" process which seems to be frowned up, despite its over whelming use. i have been attempting to setup protocol methods for what i want to do but am having zero luck. my question is, can you even have lets say a single viewcontroller send delegate requests to multiple classes? from what im finding out it doesn't seem like you can. which doesn't make sense because i thought that was the whole point of delegates and protocols with mvc. now just to clarify, i know you can have a single viewcontroller act as the delegate for multiple other viewcontrollers. but that's not what i am asking. for a simple example, lets say you have apples flip-utility template. the "done" button just calls a delegate method to the mainvc to dismiss it. now lets say we added a new class called...
#interface NewClass : NSObject <TheOtherDelegate>
and it had a delegate method...
- (void)doSomething
{
NSLog(#"The Delegate did something...");
}
can we have a button on the flipsideviewcontroller, that we wanted to call that delegate method, but still keep the "done" button call to the delegate method on the mainviewcontroller that dismisses it?
that being said, i put together a quicky project just to see if it would work and it doesn't. i came across an "answer" that says you have to instantiate the class first you want to be the delegate...
NewClass *myDelegate = [NewClass alloc] init]
[fillInMethodHere setDelegate:myDelegate];
not sure why it got a correct answer check, because needless to say it doesn't work. is there something i am missing? i scoured ib to see if there is some "delegate" connection somewhere but i couldn't find anything.
on a side note, as i was working in my working project, i read a suggestion about removing the #import and adding #class. again, that broke all kinds of things. the strange thing is before doing that, what i had so far was working and building fine. when i removed the new #class and un-commented the #import. xcode all of a sudden gave me an error "cannot find protocol deceleration for..." but yet, it worked seconds earlier. i would up having to remove the protocol code and re-add it for it to work again. very starge.
any help would be appreciated. everything iv read in docs, google, stack, etc that say something should work, don't in an actual project.
A "delegate" isn't some fancy object. It's simply a synthesized property of type id called delegate. If you wanted to, you could have an arbitrary number of properties that all conformed to the same protocol. Then when you wanted to issue a callback, you would just address all of them:
[self.mydelegateA doSomething];
[self.mydelegateB doSomething];
etc.
You could also have an NSMutableArray property that you could add objects to, and then use [self.myMutableArrayOfDelegates makeObjectsPerformSelector:#selector(doSomething)].
Finally, there's always the route of NSNotificationCenter (not to be confused with push notifications) is a class that provides an inter-object messaging system. Many objects can register for a message that any other object can send.
Please see the Apple's documentation for more information. Click Here.
Regardless of the fact that this is OS X documentation, it's still quite good at explaining things visually: click here.
Here's an example of simply changing the name of the delegate property: click here
And here's an example of adding another protocol and a second delegate: click here
Finally, here's an example that builds on the previous two and has a third delegate that also conforms to the same protocol: click here
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.
I am using UIViewController (a subclass of course) with a text field which sends an action when the contents changed (to the contentsChanged: selector of the ViewController). It is done by sending contentsChanged: to file's owner in IB.
But when I test it, it says : "-[NSCFString contentsChanged:] : unrecognised selector sent to instance " and the instance pointer in hex.
I am guessing that for some reason the view controller gets moved to another pointer and a string gets allocated there, but I cannot figure why.
Any ideas ?
Sounds like a classic case. Read up on NSZombieEnabled for how to track this sort of problem down.
I have the exact same problem with a subclass of UIViewController and this piece of innocuous code:
- (void)viewDidLoad
{
NSLog(#"%# %s %#", [self class], _cmd, answerButton);
[self.answerButton addTarget:self
action:#selector(getAnswerToQuestion:)
forControlEvents:UIControlEventTouchUpInside];
}
Yes, answerButton is connected (it's an IBOutlet), yes, - (IBAction)getAnswerToQuestion:(id)sender; is a proper method, but no joy. When I commented out the viewDidLoad and made the connection in IB, it showed in the crash report that the failure happens on [UIControl sendAction:to:forEvent:] resulting in
objc_msgSend() selector name: performSelector:withObject:withObject:
I can't prove it, but I suspect there's a bug somewhere in the UIKit that translates the bindings and addTarget to a call to performSelector. I'm planning to upgrade to iOS 4.01 first to see if that won't solve the problem.
UPDATE:
I'm not sure anymore that my problem really is similar to Alexandre Cassagne's but in the interest of sharing information I will not delete it just yet. I solved my problem, as so often, when I started to make an example project in order to file a bug report. Yes, clicking made answerButton call getAnswerToQuestion: like a good little object and all was fine.
The difference between the subclassed UIViewController of the example project and that of my real project was that the first also functioned as the xib's File's Owner while the second was just one of several view controller. When I moved getAnswerToQuestion: to the File's Owner in my real project, clicking answerButton worked as expected. So, my hunch that the problem lay somewhere in the translation from binding to performSelector wasn't that far off: the problem lies in the Responder Chain. I would think that establishing the Action-Target link either programmatically or in IB would bypass the Responder Chain, but apparently not.
The problem now, of course, is that Alexandre states in his question that his contentsChanged: method already is part of the File's Owner, which makes my answer irrelevant to the question.
without looking at the code, it looks like you are calling contentsChanged: on the text field's text, instead of the UIViewController subclass.
you should consider using the UITextFieldDelegate protocol to get called back when the text of a UITextField changes. I have not looked, but this is the thing I would do off the top of my head.
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.
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.