I get the following error after I change the rootViewControler of my UIWindow.
2012-10-16 15:12:35.653 repdocApp[22898:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSNotificationCenter dictationViewClass]: unrecognized selector sent to class 0x1d63914'
The strange thing is, it only occurs if I have a line in my code which will never be executed at this time.
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate *app = (AppDelegate *) [[UIApplication sharedApplication] delegate];
OverviewModel *model = [self.dataArray objectAtIndex:indexPath.row];
if (model.modelType == ModelTypeCatalog)
{
NSLog(#"HERE");
if (app.window.rootViewController == app.catalogViewController)
{
return;
}
// with this return no error but this branch is never executed
// return;
[UIView transitionFromView:app.window.rootViewController.view
toView:app.catalogViewController.view
duration:0.45f
options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished){
app.window.rootViewController = app.catalogViewController;
}];
}
else
{
if (app.window.rootViewController == app.catalogViewController)
{
[app.navigationPopoverController dismissPopoverAnimated:NO];
[UIView transitionFromView:app.window.rootViewController.view
toView:app.splitViewController.view
duration:0.45f
options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished){
app.window.rootViewController = app.splitViewController;
}];
}
}
}
I search the whole internet but I found nothing about +[NSNotificationCenter dictationViewClass] or what this can be.
EDIT:
I notice now, it only happens if I change the rootViewController in a transition, if I do it directly no error happens.
Your Error Log is 2012-10-16 15:12:35.653 repdocApp[22898:c07] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSNotificationCenter dictationViewClass]: unrecognized selector sent to class 0x1d63914
You are calling wrong method .dictationViewClass does not exist in ios.
It's Simply mean you are trying to call a methods which is not exist for Corresponding Class (NSNotificationCenter).
You should Change set Notification as below
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(yourMethodWantToExcute:) name:#"NSNotificationName" object:nil];
I hope It'll be helpful to You.
unrecognized selector sent to class means that there is no such method defined for this class. Try:
Delete the line and try if it works.
Look for a category withn your sources if it contains this method
Write your own blank method with the same name
Try to figure ouy what this method meant to do and implement it
Its not a real answer on this but the same error happens on different actions again regardless of an animation.
The problem seems to be the change of the rootviewcontroller, I replace that with a hidden tabbarcontroller and switch between the tabs and the problem is gone.
Related
I got a strange error. After I installed my test app in release mode I got an error:
[SomeMapView setRotateEnabled:]: unrecognized selector sent to instance 0x1c58ac40
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SomeMapView setRotateEnabled:]: unrecognized selector sent to instance 0x1c58ac40'
The Mapview was initialized and in the init method I was trying to deactivate the rotation. In the debugging mode it worked fine.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setRotateEnabled:FALSE];
[self initDelegate];
}
return self;
}
Maybe someone knows what's going on? Thanks in advance.
It was a problem in the iOS version. RotateEnabled in available only in iOS7 like Suresh point out. I had to check if the property was there (or check if it has iOS7) like
if ([self respondsToSelector:NSSelectorFromString(elementName)])
{
[self setValue:elementInnerText forKey:elementName];
}
I have a data manager (singleton class) that loads JSON from my backend service and then perform some caching in it, write it to disk, etc
so then I put this method inside a :
dispatch_sync(dispatch_queue_create("com.testing.serialQueue", DISPATCH_QUEUE_SERIAL), ^{
//my method that does disk caching here
});
inside this method when everything is done, I have a UINotification using the following:
dispatch_async(dispatch_get_main_queue(),^{
[[NSNotificationCenter defaultCenter] postNotificationName:kNewStoriesNotification object:nil userInfo:userInfo];
});
and inside the notification I do the following:
[self.collectionView performBatchUpdates:^{
if ([highlightItems count] > 0){
//doing some computation to find the index path
[weakSelf.collectionView insertItemsAtIndexPaths:indexPathArray];
}
} completion:^(BOOL finished) {
}];
and it sometimes gives me this error:
*** Assertion failure in -[UICollectionView _endItemAnimations], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionView.m:2662
I am not sure why.. but my guess is that it has to do with my use of GCD and notification. Any ideas?
UPDATE:
Even if I remove the insertItemsAtIndexPaths: it still crashes at performBatchUpdates.. wonder why
I have a view which loads data via an NSOperation within an NSOperationQueue. I want to allow users to leave this view before the operation has completed. My problem is that I can't seem to consistently do this without crashing. Here is my code to start the operation:
NSOperationQueue* tmpQueue = [[NSOperationQueue alloc] init];
self.queue = tmpQueue;
[tmpQueue release];
SportsLoadOperation* loadOperation = [[SportsLoadOperation alloc] init];
[loadOperation addObserver:self forKeyPath:#"isFinished" options:0 context:NULL];
[self.queue addOperation:loadOperation];
[loadOperation release];
If I leave the view while the operation is still executing, I often get this error:
[SportsViewController retain]: message sent to deallocated instance 0x38b5a0
If I try to remove the observers so that this doesn't occur, like this:
-(void)viewWillDisappear:(BOOL)animated {
if (self.isLoadingData) {
for (NSOperation *operation in [self.queue operations]) {
if([operation isExecuting]) {
[operation cancel];
[operation removeObserver:self forKeyPath:#"isFinished"];
}
}
}
[super viewWillDisappear:animated];
}
Then I sometimes get this error:
Terminating app due to uncaught exception 'NSRangeException', reason:
'Cannot remove an observer <SportsViewController 0x661c730> for the key path "isFinished" from <SportsLoadOperation 0x66201a0> because it is not registered as an observer.'
How can I avoid these problems?
The 2nd error message says it all.
Have you tried to not removeObserver after [operation cancel] and see what happens then?
Have you tried to first removeObserver and only then cancel the operation?
These might help to narrow down the conditions that trigger the error. Also, you might want to add log output to the code to see when it actually executes.
And, like freespace's answer says, adding & removing observers is best done in the construction / destruction methods of the observed instances. This generally yields more stable code.
Looks like you have an instance of SportsLoadOperation that doesn't have SportsViewController as an observer. Are you inserting SportsLoadOperation anywhere else in your code? If this is the case, consider writing an initWithObserver method for SportsLoadOperaion that will do the observing automatically. This avoids errors caused by forgetting to set the observer on isFinished.
Also, it is probably better to do the removal of observer in dealloc then in viewWillDisappear because viewWillDisappear is called in many circumstances, e.g. when displaying a modal view controller. Thus you might be prematurely stopping your operations.
Edit
Instead of checking against [operation isExecuting] check against [operation isCancelled]. This is because [operation cancel] doesn't stop an operation - it can and will continue executing if you don't actually check for isCancelled in your main method. This means that if viewWillDisappear is called twice, you could end up attempting to call removeObserver twice on the same instance of SportsLoadOperation, with the second attempt failing.
Add some debugging output statements in the following places:
when you create a SportsLoadOperation instance and insert it into the queueu
when you are cancelling a SportsLoadOperation instance and removing from it observers.
I ended up solving this by overriding the observed operation's addObserver and removeObserver methods, to keep track of observers so I could remove them in the [cancel] method.
All I have to do now is call the operation queue to cancel all operations before I dismiss the controller that was observing the operations.
Below, _observers is an NSMutableDictionary.
- (void)addObserver:(NSObject*)observer
forKeyPath:(NSString*)keyPath
options:(NSKeyValueObservingOptions)options context:(void*)context
{
[super addObserver:observer forKeyPath:keyPath options:options context:context];
[_observers setValue:observer forKey:keyPath];
}
- (void)removeObserver:(NSObject*)observer forKeyPath:(NSString*)keyPath
{
[super removeObserver:observer forKeyPath:keyPath];
[_observers removeObjectForKey:keyPath];
}
- (void)cancel
{
[super cancel];
for(id key in _observers)
{
id object = [_observers valueForKey:key];
[super removeObserver:object forKeyPath:key];
}
[_observers removeAllObjects];
}
I have a MasterViewController.h.m.xib (UIViewController) that is opening a TestDummy.h.m.xib (UIViewController) in the following way:
TestDummy *controller = [[TestDummy alloc] initWithNibName:#"TestDummy" bundle:nil];
[scrollView addSubview:controller.view];
I have two buttons in TestDummy: (Open), (Close) and one label: (windowDepth).
I'm trying to create a second instance TestDummy that is open by the first TestDummy. Then allow multiple TestDummy (UIViewController) to open to N depth and allow the close button to take them back to zero depth. Here's what i have for my Open button.
-(IBAction) btnOpen_Clicked{
TestDummy *newController = [[TestDummy alloc] initWithNibName:#"TestDummy" bundle:nil];
newController.isNotRoot = YES;
newController.windowDepth = self.windowDepth + 1;
//do stuff...
childDummy = newController;
// start the animated transition
[UIView beginAnimations:#"page transition" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
//insert your new subview
[self.view addSubview:newController.view];
// commit the transition animation
[UIView commitAnimations];
[newController release];
}
When i do this i get an error in the debug console.
2010-10-07 00:59:12.549 OrionClient[5821:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType btnOpen_Clicked]: unrecognized selector sent to instance 0x6a339a0'
Must be a memory management issue but i can't figure it out.
Thanks in advance.
'NSInvalidArgumentException', reason:
'-[__NSCFType btnOpen_Clicked]:
unrecognized selector sent to instance
0x6a339a0'
It means you are trying to call a non existing method on that instance. How have you defined the btnOpen_Clicked selector? I'm guessing it should look more like, but really need to see how you defined the selector.
-(IBAction) btnOpen_Clicked:(id)sender
It means that the application can't find your method btnOpen_Clicked.
First rename your method with :
-(IBAction) btnOpen_Clicked:(id)sender
Then make sure this method specification is in the .h file
And in InterfaceBuilder with your TestDummy.xib, make also sure that the link between the button and this method is correctly done with for example TouchUpInside event.
solved it removed the last line [newController release]; need to figure out where to actually call this correctly though.
Ok, I've spend like half day on this and it's killing me.
So I've got 3 view controllers transitioning from one another, something like this:
I call the UploadDecisionViewController after destroying the previous View Controller:
[self dismissModalViewControllerAnimated:YES];
[self performSelector:#selector(showUDModalView) withObject:nil afterDelay:0.5];
In my showUDModalView method:
- (void)showUDModalView
{
UploadDecisionViewController *udcontroller = [[UploadDecisionViewController alloc] initWithNibName:#"UploadDecisionViewController" bundle:nil];
udcontroller.delegate = self;
[self presentModalViewController:udcontroller animated:YES];
[udcontroller release];
}
The UploadDecisionViewController shows up no problem. The UploadDecisionViewController has a button, which when clicked I want it to transition to the FileUploadViewController. I setup a UploadDecisionDelegate, threw a method in there to handle the button clicking:
Inside UploadDecisionDelegate protocol (UploadDecisionViewController.h):
#protocol UploadDecisionDelegate
//let UOnliveViewController know that a button was selected
- (void)UploadDecisionViewController:(UploadDecisionViewController *)controller madeChoice:(NSString *)whichDirection;
#end
Then inside my IBAction method when the button is clicked, I have this:
- (IBAction)decisionSelected:(id)sender
{
[delegate UploadDecisionViewController:self madeChoice:#"upload"];//crashing at this line
}
When I run this, at this line above it is throwing a runtime exception:
2010-06-09 12:48:59.561 UOnlive[4735:207] *** -[UIView UploadDecisionViewController:madeChoice:]: unrecognized selector sent to instance 0x3b65420
2010-06-09 12:48:59.562 UOnlive[4735:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView UploadDecisionViewController:madeChoice:]: unrecognized selector sent to instance 0x3b65420'
2010-06-09 12:48:59.563 UOnlive[4735:207] Stack: (
33502299,
2495698185,
33884219,
33453686,
33306306,
20618,
2982917,
3390286,
3399023,
3394235,
3087839,
2996168,
3022945,
40156505,
33287040,
33283144,
40150549,
40150746,
3026863,
11700,
11554
)
Let me throw in the delegate method implemented also:
- (void)UploadDecisionViewController:(UploadDecisionViewController *)controller madeChoice:(NSString *)whichDirection
{
NSLog(#"it got to here 245");
[self dismissModalViewControllerAnimated:YES];
if (yesOrNo) {
//open up the FileUploadViewController and proceed to upload
[self performSelector:#selector(showFUModalView) withObject:nil afterDelay:0.5];
}
}
Can someone tell me what the heck is going on? Thanks a bunch for the help...
The error says that you are trying to call the UploadDecisionViewController method on UIView.
My bet is that you set some view to the delegate instead of view controller.
Where the showUDModalView method is located?
Maybe you set the delegate in some additional places?
Your code is to lengthy and I dont want to go through this but just an advice, you can c if your object can/cannot perform a selector with this kind of statement:
if([myObj respondsToSelector:#selector(myFunc)])
{
//do something
}
else{
//do something else
}