performSegueWithIdentifier: causes app to crash - ios

I have a button that is pressed after user enters email information. I have an alert view that is displayed when there is no email entered but if there is I want the button to segue to another view controller.
The following code causes my app to crash. I have no idea why. Please help.
(note: I have tried "sender:self]" "sender:nil]" and "sender:sender]" and they all make my app crash.)
- (IBAction)nextButtonPushed:(id)sender {
if ([self.emailTextField.text isEqual: #""]) {
emailAlertView = [[UIAlertView alloc] initWithTitle:#"Missing Email" message:#"A destination email is required to send." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[emailAlertView show];
self.nextButton.enabled = NO;
}
else {
eString = self.eTextField.text;
hString = self.hField.text;
emailAddress = self.emailTextField.text;
[userDefaults setObject:eString forKey:#"e"];
[userDefaults setObject:hString forKey:#"h"];
[userDefaults setObject:emailAddress forKey:#"email"];
[self performSegueWithIdentifier:#"next" sender:self];
}
}

There are three overwhelmingly likely possibilities:
Perhaps the storyboard really has no segue named "next" emerging from the FirstViewController scene. Be careful: spaces and capitalization and things like that matter.
Perhaps the storyboard has a segue named "next" but it emerges from a different scene (a different view controller).
Perhaps the FirstViewController instance represented by self in your code is not the same as the FirstViewController instance in the storyboard, i.e. maybe it came into existence in some other way and not by instantiation from the storyboard. You might even have two FirstViewController objects in the storyboard, and the segue comes from the other one.

One great way to figure out why your app is crashing on a line like this is to disable any breakpoints you may have (including exception breakpoints). This will cause the app to crash and often tell you a reason why it is crashing. Normally you'll get error's like #matt mentioned such as bad identifiers on your seques (often typing errors), multiple of the same object in an IB scene such as the following:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<YOURAPP.YOURVIEWCONTROLLER: 0x7c8951d0>) has no segue with identifier 'TheSequeIdentifierYouHaventSetYetOrTypedInWrong''
or like in my case today where I got this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<YOURAPP.YOURVIEWCONTROLLERYOUARETRYINGTOSHOW 0x78e5a140> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key "MyKeyOnTheOffendingObject"
Once I knew that I had an object in my storyboard with a key that it should not have all I had to do was track down the Button/Image/Other Random Object with the bad Referencing Outlet or Sent Event and all was fixed
Often performSequeWithIdentifier will come up as the last line shown before a crash since that is the last line that worked before a problem was found when presenting a new View Controller - so if you are sure the problem isn't with your seque then check references on the VC you are trying to present!

Crashing can also occur if the view controller cannot load from the NIB. For example if there is an incorrectly named User Defined Runtime Attribute.
For example QBFlatButton changed their API today and my app started crashing. This is why we use semantic versioning :-)

Related

BAD_ACCESS & NSInvalidArgumentException in working with UIPickerView

I'm beginner in working with UIKit. When I tired to work with UIPickerView in iOS 7 SDK I faced to a hard-to-solve problem.
We know that UIPickerView needs two resources to work perfectly: dataSource & delegate. So I wrote a class named "KMPickerProtocols". I adopted it to UIPickerViewDataSource & UIPickerViewDelegate Protocols and then I added some extra setter methods to it.
KMPickerProtocols is adopted to all of essential methods of dataSource and delegate Protocols + the necessary optional method for setting title of each row (pickerView:titleForRow:forComponent). all these methods get things done without any problem (in normal situations).
Finally I set the delegate and dataSource properties of my UIPickerView (named _accountPicker) manually with this piece of code:
NSArray *delegateAgent = [[KMTwitterDelegate new] run ];
_accountPicker.dataSource = [delegateAgent objectAtIndex:0];
_accountPicker.delegate = [delegateAgent objectAtIndex:1] ;
(the run method is designed to set some properties including height of each row and ...)
Now, when I run my app it will show my twitterAccounts stored in system(accounts framework) in the form of UIPickerView. but there is a problem: As soon as I scroll the picker view or tap on any row, the program will crash and I get BAD_ACCESS (code=2 , address = 0x1) in this line of code:
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([KMAppDelegate class]));
}
and also there are sometimes that I get signal SIGABRT in above line. in these situations Log Says:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSMallocBlock pickerView:titleForRow:forComponent:]: unrecognized selector sent to instance 0x8c75ad0'
I will appreciate if you help me to deal with this problem. I really don't know where the bug is. but I guess this screen shots will be helpful to find that:
The problem in above screenshot is that UIPicker called the "pickerView:titleForRow:forComponent" method for row 0, three times instead of one time. I just don't know whether that is this because myFault or because the typical behaviour of UIPicker.
You are sending the message pickerView:titleForRow:forComponent: to an object of type NSMallocBlock. This is a message automatically sent from the picker to its datasource, so my assumption is that you are assigning the datasource:
_accountPicker.dataSource = [delegateAgent objectAtIndex:0];
The datasource you assign does not conform the protocol UIPickerViewDataSource
Checkout what returns [delegateAgent objectAtIndex:0]; and make sure it is what you expect it to be.

New view from UIBarButtonItem?

So I've seen previous questions similar to this but they were of no help. I've read Apple's documentation too but I could not understand where I've gone wrong. AFAIK I did everything logically, but when I click on my done button on an UItoolbar overlay, the button can be pushed but it does not do anything. This obviously means it fails to acknowledge the written code. But how?
I want to bring up the .nib of "TableViewController" when a done button is clicked on my UIToolBar. But the below isn't allowing the click to bring up a new view. How do I rectify this? Please show me where I went wrong and what should be replaced and why.
-(void)doneButtonPressed {
TableViewController *UIView = [[TableViewController alloc]
initWithNibName:#"TableViewController" bundle:nil];
UIView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:UIView animated:YES];
[UIView release];
}
Whoa, you've got some bizarre stuff going on here. In your first line, you're allocating and initiating the TableViewController instance correctly, but you're not giving that instance a unique name. You're naming it with another class's name, which is bound to stir up problems. In fact, I'm surprised it didn't through an error.
Try the following instead:
TableViewController *tableView = [[TableViewController alloc]
initWithNibName:#"TableViewController" bundle:nil];
tableView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:tableView animated:YES];
Now, your TableViewController instance has a unique name that is referenced throughout the rest of the method. Just to be clear--UIView is another class name, and therefore cannot be used as the name of an instance of an object.
EDIT: Additionally, be sure to add your button's selector doneButtonPressed: to your .h file of its view controller. Also, if you like you can toss an NSLog() call in the beginning of the function just to be sure it isn't (or perhaps is) being called.
Something to check when button actions aren't firing is that you've got the appropriate selector. If you've followed the selector correctly. Make sure you aren't using a selector of
#selector(doneButtonPressed:)
which would look for a function like:-
- (void) doneButtonPressed:(id) sender
For your member function, you need
#selector (doneButtonPressed)
The debugger is your friend here. Start with a breakpoint to make sure your function is being called.
If you're getting into the function, then The Kraken's answer is the next thing to check.
There is no restriction on using a class name as a variable name whatsoever. Although you should change it because its confusing and doesnt follow iOS coding conventions.
"Button can be pushed but doesnt do anything", is the selector even being called?
-(void)doneButtonPressed
Show how you created the UIBarButtonItem to verify that you provided the right selector in the init method or that you connected the button directly in interface builder (which it doesnt look like since you didnt use the (IBAction) return signature.

Exception: terminate called throwing an exceptionsharedlibrary apply-load-rules all

I am trying to pull a VC xib, by adding the view of controller on window's view. When I execute the program nothing appears (a black screen), and expectation was a button put on view of VC in xib.
But when I declare that this VC is my Project's main interface (Project Summary), then it throws the exception : terminate called throwing an exceptionsharedlibrary apply-load-rules all and application crashes.
Here is the code for didfinishlaunch (Appdelegate)
[self.window addSubview:rootViewController.view];
[self.window makeKeyAndVisible];
Can somebody assist on that.
Thanks
PS: the complete error is given below
2012-02-26 11:50:08.003 PasswordGeneratorTest[1161:f803] * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.'
* First throw call stack:
(0x13b9052 0x154ad0a 0x13b8f11 0x9b0032 0x921f7b 0x921eeb 0x93cd60 0x22f91a 0x13bae1a 0x1324821 0x22e46e 0x230010 0x1014a 0x10461 0xf7c0 0x1e743 0x1f1f8 0x12aa9 0x12a3fa9 0x138d1c5 0x12f2022 0x12f090a 0x12efdb4 0x12efccb 0xf2a7 0x10a9b 0x1d42 0x1cb5)
terminate called throwing an exceptionsharedlibrary apply-load-rules all
Current language: auto; currently objective-c
Single stepping until exit from function __pthread_kill,
which has no line number information.
I can't see your stack trace code or the message the debugger is giving you, but there's ALWAYS 2 reasons why it would crash here:
rootViewController.view is nil or doesn't have its view outlet set in IB.
self.window is not set in code or doesn't have its outlet connected in IB.
Check all of your outlets and see if it fixes it.

iOS - Getting a weird error: unrecognized selector sent to instance on a UITableView

Introduction
In my current application I have a UITableView which holds custom cell objects. The custom UIViewCellObjects are simply subclassed from the standard UITableViewCell class. The custom cells holds information about running background uploads, and updates them with things like percentage done and so on.
The custom cell objects listens to NSNotifications from upload processes running in the background, and when they get a relevant notification, they simply update their own view controls with the new information (such as upload percentage).
Now when an upload process is done, I re-order the array of active upload objects and reload the tableview like this:
-(void) uploadFinished: (NSNotification*)notification
{
NSDictionary *userInfo = [notification userInfo];
NSNumber *uploadID = [userInfo valueForKey:#"uploadID"];
if (uploadID.integerValue == uploadActivity.uploadID)
{
[[ApplicationActivities getSharedActivities] markUploadAsFinished:uploadActivity];
[parentTable reloadData];
[self setUploadComplete];
}
}
Now this method takes place in the tableviewcell objects, and as you can see they call their owning UITableView to reload the data right after the array is sorted. The markUploadAsFinished method simply re-orders the array so any newly finished upload is put at the top, so it will appear this way in the UITableView.
The Problem
Now the problem I'm having is that when this method is called, I sometimes get the following error:
'NSInvalidArgumentException', reason: '-[CALayer tableView:numberOfRowsInSection:]: unrecognized selector sent to instance
I do not get it all the time, sometimes the entire process runs fine and finished uploads appear in the start of the UItableview, and at other seemingly random times it fails. I don't really have a clue what's going on here.
The custom cells are loaded from a .NIB file like this:
UploadCell *cell = [activeUploadsTable dequeueReusableCellWithIdentifier:#"UploadProgressCell"];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"UploadCellView" owner:self options:nil];
cell = customCell;
}
Is there anyone who might have a clue about what's going on here?
EDIT
First of all, I have tracked down this error to appear right at the line where:
reloadData
is called inside of the custom cell objects.
Furthermore, it seems that the instance it sends methods to can change. I just got this error too:
'NSInvalidArgumentException', reason: '-[UIScrollViewPanGestureRecognizer tableView:numberOfRowsInSection:]: unrecognized selector sent to instance
I really have no idea what's going on here.
'-[CALayer tableView:numberOfRowsInSection:]: unrecognized selector sent to instance
You've got a bad pointer. It looks like your table's data source is being released while the table still exists. The table doesn't retain its data source because that could create a retain cycle. If you don't take care to keep the data source around while the table is using it, the table will can up with a pointer to an object that no longer exists. In this case, it looks like a CALayer object is subsequently being created at the same address. When the table later sends its "data source" a message to get the number of rows, that message is delivered to the layer, which (obviously) doesn't have a -tableView:numberOfRowsInSection: method, and the error results.
According to me you running the upload process method in background i think other thread than main thread. And according to my knowledge when you deal with UIKIT objects you have ruin on main thread.
But these problem not occur every time because some time you switch to other thread to main thread so its working fine and some time not. so that problem occur

Popovers in UITableView

I would like to display popovers with UITableView's as content (this works) on some button presses and then get the selected item as string as buttontitle or some textview text. I've found a few example on how to do this with protocols but still get an error.
My code:
In popoverViewController.h
#protocol popoverViewControllerDelegate <NSObject>
-(void)getRowText:(NSString *)string;
#end
I declare an id delegate2 variable and set its property to:
#property(nonatomic,assign) id<popoverViewControllerDelegate> delegate2;
In the popoverViewController.m file I synthesize the variable, and in didSelectRowAtIndexPath method I have this, and this line seems to cause the error I`m having:
[self.delegate2 getRowText:[someArray objectAtIndex:indexPath.row];
In mainViewController.m I add the popoverViewControllerDelegate to the ViewControllers protocol and have its header file imported. And then have some code in the -(void)getRowText: method which doesnt get called.
UIPopovers and such are set up as they work as needed, problem arises when I press a row in the tableview. I get the
Terminating app due to uncaught
exception
'NSInvalidArgumentException', reason:
'* -[UIPopoverViewController
getRowText:]: unrecognized selector
sent to instance 0x57ca80'
Could anyone give some advice with this?
Finally found the error and cant believe how silly I/it was.
I had a viewController.delegate2 = self. line with period instead of a semicolon, I wonder why it compiled tho.

Resources