Table View Controller delegate is nil, but should be a valid reference - ios

I'm designing a simple Grocery List app, but having trouble adding a Food entity to a List entity.
Sequence of events: ListDetailTVC -> AddFoodToListTVC -> type in food name -> save
at this point I want to see this food in the list, but instead nothing happens. The screen stays the same. After some delving into I realized the delegate was nil in AddFoodToListTVC, so there was no screen to return to after 'save' was pressed.
Then I tried manually setting the delegate with the following code:
`if(delegate == nil)
{
self.delegate = (ListDetailTVC *)[[UIApplication sharedApplication] delegate];
}
NSLog(#"delegate = %#", delegate);
`
This sets the AddFoodToListTVC delegate to something, but I'm not sure how to verify Im setting it correctly. When I run my app with the above addition, I get this error when I click save.
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate theSaveButtonOnTheAddFoodToListTVCWasTapped:]: unrecognized selector sent to instance 0x6b56610' "
0x6b56610 in this case is the address of the delegate I am manually setting.
I know that's not much info, but I can supply any relevant code. Im at my wits end, how do I set the delegate for AddFoodToListTVC correctly?

It looks like your app delegate does not implement this method: theSaveButtonOnTheAddFoodToListTVCWasTapped:

Delegates are something like event triggers which are received by delegated object... like rowWasSelected is an event which needs to be handled by someone for the mandatory methods....
Now the thing is ur setting AppDelegate as the receiver object for delegates [self.delegate = (ListDetailTVC *)[[UIApplication sharedApplication] delegate];]...
But as AppDelegate doesnt handle those events, you get an exception [unrecognized selector]...
So first thing is declare protocol i.e., UITableViewDelegate, UITableViewDataSource... [protocols are like interface which has only declaraion not implementation, you need to provide implementation] Set tableViews DataSource and Delegate and implement those protocols. Will solve your problem

Related

Why do I get the error "Unrecognized selector sent to instance error"

I'm just learning Objective C and have come across this issue. I have created a simple manager class like so
#import <Foundation/Foundation.h>
#interface PassManager : NSObject
- (void)isValidCredentials:(NSString *) username
withPassword:(NSString *) password
wasValid:(void(^)(BOOL success))handler;
#end
the implementation is as follows
#import "PassManager.h"
#implementation PassManager
- (void)isValidCredentials:(NSString *) username
withPassword:(NSString *) password
wasValid:(void(^)(BOOL success))handler
{
handler(true);
}
#end
This builds but upon running I get the error:
"2016-01-27 16:40:41.555 MessyApp[19395:897750] -[PassManager initWithConfiguration:]: unrecognized selector sent to instance 0x7fd12a413d30 2016-01-27 16:40:41.560 MessyApp[19395:897750] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PassManager initWithConfiguration:]: unrecognized selector sent to instance 0x7fd12a413d30'".
What am I doing wrong?
Well the error says it all, somewhere in your code you are calling the initWithConfiguration method on an PassManager but you don't have that method in your PassManager class, so it throws an exception.
Either add the method and implement it in your PassManager class, or if you want to catch exactly where this is happening (and don't want to search for all the occurrences of initWithConfiguration.
You could go to Breakpoint Navigator by pressing CMD+7 and then on the bottom press the + sign and add an Exception Breakpoint, run the app and wait for it to fire.
Good luck.
After speaking to originaluser2 he showed me it was something else causing the problem. I was using a library called Parse that required startup code in the appdelegate class and it was that what was blowing up. Once he showed me that I looked at what else I did and realised I had created a class called ParseManager that was causing some sort of name conflict. I changed this classes name and sure enough it all started working. Bad question on my part I'm afraid but Im a new to this platform

Firguring out reasons for exceptions in Objective-C

After I completed the tutorial: Start Developing iOS Apps Today
I got the same exception asked here: IOS Tutorial Exception (ToDo Sample)
and the app crashed but it would not crash if I started a debugging session and stepped through the code.
2015-05-04 16:09:51.569 ToDoList[9223:67681] -[AddToDoItemViewController textField:]: unrecognized selector sent to instance 0x7fe570d4eff0
2015-05-04 16:09:51.574 ToDoList[9223:67681] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AddToDoItemViewController textField:]: unrecognized selector sent to instance 0x7fe570d4eff0'
Then I solved the mystery by reading out this post: IOS Tutorial Exception (ToDo Sample)
The reason was that I wrongly connected the text field to the #implemenation section instead of to the #interface section and it created some method that I deleted. Of course I forgot about that soon after that.
How could I have figured out myself without knowing anything of the above what was the reason to get that exception and where it came from?
Log message is telling you that something was trying to call -textField: method of your AddToDoItemViewController.
So the first step would be to check if that method is implemented - in your case it was not. You might have been confused by the presence of
#property(weak, nonatomic) IBOutlet UITextField* textField
but auto synthesis for property generates getter with the signature -textField, which is different from -textField: (latter takes one parameter, while former none).
The exception says that you're trying to access the textView property of AddToDoItemViewController, but it doesn't have one.
So your next step would've been to go and check that you have a property like that declared and being an outlet that it's properly connected in the Interface Builder.
Edit:
Sorry I wasn't paying enough attention.
The selector that it's trying to call is textField: so it must be a function starting like that. I assume you set the controller as a TextView delegate but didn't implement the required method.

Odd error (UITextSelectionView) while calling a method?

I'm facing a problem while calling a method and I don't know how figure it out.
Basically, during the main menu, I want to call a SKNode showing a tutorial part. The code is the following:
- (void)didMoveToView:(SKView *)view
{
...
if ([[GameData sharedData] openingTutorial]) { // Checks if the menu needs the tutorial
[_tutorialObj performSelector:#selector(runTutorialWithStep:)
withObject:[NSNumber numberWithInt:8]
afterDelay:3.0
];
}
}
When the method didMoveToView: is called (even before waiting the 3 seconds for the runTutorialWithStep:), I got this error:
[UITextSelectionView name]: unrecognized selector sent to instance 0x1576e6c0
2014-10-14 11:01:19.430 [406:130379] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITextSelectionView name]: unrecognized selector sent to instance 0x1576e6c0'
The odd thing is that in the previous class I use the same tutorial's action in the didMoveToView: and it's working right. But...
Thing is getting more strange here!!!
If I use an intermediary method for this calls:
- (void)didMoveToView:(SKView *)view
{
...
[self performSelector:#selector(intermediaryMethod)
withObject:nil
afterDelay:3.0
];
}
- (void)intermediaryMethod
{
[_tutorialObj performSelector:#selector(runTutorialWithStep:)
withObject:[NSNumber numberWithInt:8]
afterDelay:0.0
];
}
Everything works without issues. I don't want to avoid the problem but solve this. Any advices?
The error says it all. You try to send a 'name' message to object that doesn't implement it (UITextSelectionView). Since your second take works the cause is either in
[[GameData sharedData] openingTutorial]
method or before this call. Search for objects calling 'name' and check if it's the UITextSelectionView in question.
That or maybe you have weak reference to general view object and during those three seconds before calling runTutorialWithStep you reassign it to object that implements 'name' message.
Ok, I solved the problem.
I added a breakpoint for every exception and I realized that the issues was due to an other class (the only one with UITextView).
Basically I removed the text field from its parent ([self removeFromParent]) by my own once I did not need it anymore.
I suppose the error was fired during the deallocation 'cause the program can't find the UITextView. I managed to remove this statement and everything works right.
Actually I still have doubts because I don't understand why this exception is throw only if I call the [_tutorialObj runTutorialWithStep:] method.
I found the way to fix it.
UITextView *textView = .....
textView.selectable = NO;

lldb breakpoint, loaded nib but didn't get a UITableView

I have an app with no nibs. Its rootviewcontroller is a tableviewcontroller. I am having it push to a second tableviewcontroller, which controls a detailview. Just earlier this week, I had it successfully pushing to the next tableviewcontroller. A few days later (and after maybe saving the wrong version),
I get an
(lldb) with a breakpoint at the pushViewController method when I select a table item. I have breakpoints for all exceptions enabled. If I press the play button twice more, I get this in my output box:
" ** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "TopicsDetailViewController" nib but didn't get a UITableView.'"
Is there something wrong here or do I need to look elsewhere in my project?
This is in my header interface:
TopicsDetailViewController *tdvController;
: ) And this is my didSelectRowAt...
tdvController = [[TopicsDetailViewController alloc] init];
tdvController.aFeed = afeed;
[self.navigationController pushViewController:tdvController animated:YES];
tdvController = nil;
Thank you, and let me know if I'm barking up the wrong tree.
If I'm understanding this correctly, your tdvController declaration in the interface file is named the same as the tdvController in the instance method where you are getting the exception.
If your intentions are to create and use the instance variable in this instance method don't declare it again, just do:
self.tdvcController = [[TopicsDetailViewController alloc] init];
Which is creating the object on the heap.
If you intentions are to use a local variable of type TopicsDetailViewController in this instance method that is not the iVar, then rename the local variable to something else.

SIGABRT in NSFetchedResultsController delegate methods after mergeChangesFromContextDidSaveNotification

The good facts:
I download data from the server, and, via Core Data thread confinement, save the data, and when the background MOC is saved, the main MOC gets merged.
All the saving operations go ok
Also the merging of the MOC happens without any problems
The bug I'm hunting:
When my UITableView with NSFetchedResultsController is active (i.e. on the screen), and the saving is happening, the app crashes with a SIGABRT that takes me to the mergeChangesFromContextDidSaveNotification line in AppDelegate.
What is the most strange part is, that when the delegate of the FRC is nil, or when it is my view controller but i don't implement any FRC delegate methods, the crash doesn't happen and I don't have any problem. But when I implement any of the delegate methods (even empty, without a single line of code), the app crashes with the same bug. It means that the methods are not even being fired, the problem is not in the code inside these methods.
The strangest part 2 (CHECK UPDATE 2 BELOW): the crash happens with a [__NSCFNumber length]: unrecognized selector sent to instance and I don't call any 'length' property in my CoreDataManager neither in my AppDelegate class
The witness: console
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(355)> Did merge
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<AppDelegate.m:(355)> Did merge
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<MyTableViewController.m:(134)> Fetched results controller did fetch
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<CoreDataManager.m:(338)> Saved data from server
[__NSCFNumber length]: unrecognized selector sent to instance 0x13318050
Some code - Merging the MOCs
- (void)managedObjectContextDidSave:(NSNotification *)notification
{
NSManagedObjectContext *sender = (NSManagedObjectContext *)[notification object];
if ((sender != self.managedObjectContext) &&
(sender.persistentStoreCoordinator == self.managedObjectContext.persistentStoreCoordinator))
{
dispatch_async(dispatch_get_main_queue(), ^{
DebugLog(#"Will merge");
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
DebugLog(#"Did merge");
});
}
}
Update 1
Following Cocoanetics hint, I created a NSNumber category to check who is calling length. I got what you see below, and a crash in [__NSCFNumber _fastCStringContents:]: unrecognized selector sent to instance.
Update 2
Enabling zombies didn't help =(
Make sure that you are only observing the notification from other MOCs. If you save there this triggers another such notification and you might be going in an endless loop that fails after one or two iterations because an object had been released by ARC.
Yours sounds like a memory issue. Check your ARC ownership qualifiers and enable NSZombies. Enabling NSZombies will help you narrow down the object that was released prematurely.
When you enable zombies you will see a "message sent to a deallocated instance" instead. Check which object was released prematurely and update your question.
Well, after months and hours, I finally got a solution. It works, and I would love to hear some opinions on why.
So, as I said, the saving was working 100%, as well as the merging notifications. If I set the NSFetchedResultsController delegate to nil, there was no problem. However, setting the delegate to my UIViewController, made the app crash.
I thought it could be, maybe due to my code when the delegate methods were triggered. But the app crashed even before that. So I followed Cocoanetics tip, to create a category and try to figure out who was calling the length method to the NSNumber object. After that, I saw that the NSPredicate was calling - (BOOL)evaluateWithObject:(id)object; before getting to the crash. In the same way, I did a category to override it:
#interface NSPredicate (PractiPredicate)
- (BOOL)evaluateWithObject:(id)object;
#end
#implementation NSPredicate (PractiPredicate)
- (BOOL)evaluateWithObject:(id)object
{
NSLog(#"Evaluate was called. Object class %#", NSStringFromClass([object class]));
MyManagedObject *myManagedObject = object;
NSLog(#"Is fault? %d", myManagedObject.isFault);
NSLog(#"myManagedObject changed and already have propertyA? %d", myManagedObject.propertyA != nil);
return YES;
}
#end
So, for my surprise, it worked, and generated te following logs:
Evaluate was called. Object class MyManagedObject
Is fault? 0
myManagedObject changed and already have propertyA? 1
I decided to print "Is fault?" because I thought that this mess was related to NSManagedObject faulting, but, for what it printed, it's not.
Question for the comments: What do you think that could have generated this problem here?
Most likely the problem does not lie in the code you posted but in how you deal with the changes in the fetched results controller delegate. Those are just being triggered by the merge.
I had the same problem and in my case, i found out that the reason for the crash was an incorrect predicate. I had a predicate like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"attribute > 0"];
Where attribute was a string. I corrected it as:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"attribute.length > 0"];
Now, my code is running fine. Make sure you check all the predicates in your code since this can also be a reason for this crash.

Resources