Ok so there have been a lot of answers to questions like this but none of them have worked for me. Basically i have written a very simple iOS app that has a label and a button. click the button and the label changes. Here is the code
//ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)buttonPressed:(id)sender;
#property (strong, nonatomic) IBOutlet UILabel *predictionLabel;
#end
//
// ViewController.m
// CrystalBall
//
//
//
#import "ViewController.h"
#implementation ViewController
#synthesize predictionLabel;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setPredictionLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)buttonPressed:(id)sender {
self.predictionLabel.text = #"Definitley Yes!";
}
#end
And when i run it in the simulator the app opens fine and then i click the "Predict" button and then it freezes and this is the error that shows up in green
Thread 1: Program recieved signal: "SIGABRT".
that is along a line that reads
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
The debugger says:
2013-01-19 22:53:30.511 CrystalBall[441:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setText:]: unrecognized selector sent to instance 0x6a19c70'
* First throw call stack:
2013-01-19 22:53:30.511 CrystalBall[441:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setText:]: unrecognized selector sent to instance 0x6a19c70'
*** First throw call stack:
(0x13b9052 0x154ad0a 0x13baced 0x131ff00 0x131fce2 0x2385 0x13baec9 0x135c2 0x1355a 0xb8b76 0xb903f 0xb82fe 0x38a30 0x38c56 0x1f384 0x12aa9 0x12a3fa9 0x138d1c5 0x12f2022 0x12f090a 0x12efdb4 0x12efccb 0x12a2879 0x12a293e 0x10a9b 0x1da8 0x1d05)
terminate called throwing an exception(gdb)
Hopefully that is enough information. Thank you!
'-[UIView setText:]: unrecognized selector sent to instance 0x6a19c70'
means that you are trying to send the setText message to a UIView instance, which does not have any such method.
This possibly comes from the statement:
self.predictionLabel.text = #"Definitley Yes!";
so you should review how you defined predictionLabel and make sure that it is of the correct type.
About the fact that you the debugger is showing you the line:
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
you should define an exception breakpoint in Xcode to catch all exceptions:
go to the breakpoints tab in the left-hand pane;
at the bottom of the pane, you will find a + icon;
click it and the select Add exception breakpoint;
confirm and it's done.
Now, the debugger shall stop on the actual line causing sigabrt so you can inspect your objects' state.
Related
I have a UIViewController QuoteViewController that has a UITableView. Inside the UITableView is a custom UITableViewCell called excessTableViewCell.
In story board I have created a custom tableview cell and assigned the custom class to excessTableViewCell and I have hooked the slider IBAction up with a ValideDidChange
This is what excessTableViewCell.m looks like.
#import "ExcessTableViewCell.h"
#implementation ExcessTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.excessLabel.text = [NSString stringWithFormat:#"$ %#", self.excessString];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (IBAction)excessValueChanged:(UISlider *)sender
{
UISlider *MySlider = (UISlider *)sender;
int SliderValue = (int)(MySlider.value/10) * 10;
self.excessLabel.text = [NSString stringWithFormat:#"$ %d", SliderValue];
}
#end
This is what my QuoteViewController tableview cell for row looks like.
// slider
NSString *cellIDString = #"excessCell1";
self.excessTableViewCell = [tableView dequeueReusableCellWithIdentifier:cellIDString forIndexPath:indexPath];
// Configure the cell...
self.excessTableViewCell.excessSlider.maximumValue = 2000;
self.excessTableViewCell.excessSlider.value = 2000 / 2;
NSInteger halfValue = 2000 / 2;
self.excessTableViewCell.excessLabel.text = [NSString stringWithFormat:#"$ %ld", (long)halfValue];
return self.excessTableViewCell;
Effectively as soon as I try to slide the value the app crashes and produces the following error.
This is what my error looks like:
2017-04-08 17:12:08.863831 Insuriato[17401:3848405]
-[QuoteViewController sliderValueChanged:]: unrecognized selector sent to instance 0x1005423f0 2017-04-08 17:18:57.449734 Insuriato[17401:3848405] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[QuoteViewController sliderValueChanged:]: unrecognized selector sent to instance 0x1005423f0'
*** First throw call stack: (0x1860f51b8 0x184b2c55c 0x1860fc268 0x1860f9270 0x185ff280c 0x18bfdfd30 0x18bfdfcb0 0x18bfca128 0x18c387758 0x18bfe7974 0x18c56a628 0x18c5666c0 0x18c5661e0 0x18c56549c 0x18bfda30c 0x18bfaada0 0x18c79475c 0x18c78e130 0x1860a2b5c 0x1860a24a4 0x1860a00a4 0x185fce2b8 0x187a82198 0x18c0157fc 0x18c010534 0x100087a3c 0x184fb15b8) libc++abi.dylib: terminating with uncaught exception of type NSException
I just build a class to manage correctly my database and JSON request. The problem is that now, how can I perform the segue ?
Here is my code
In my view :
- (IBAction)loginClick:(id)sender
{
NSString *post = [NSString stringWithFormat:#"username=test&password=test"];
[[DataManagement sharedManager] WebServiceLogin:post];
}
- (void) showTypeView
{
[self performSegueWithIdentifier:#"showTypeView" sender:nil];
}
In my class :
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
...
switch ([[response valueForKey:#"success"] intValue])
{
case 0:
{
NSLog(#"error: %# error Description: %#", [response valueForKey:#"success"], [response valueForKey:#"error_message"]);
break;
}
case 1:
{
LoginViewController *showView = [LoginViewController new];
[showView showTypeView];
break;
}
default:
break;
}
...
}
When I launch, I have an error :
**
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<LoginViewController: 0x165afd30>) has no segue with identifier 'showTypeView''
*** First throw call stack:
(0x2592e2eb 0x250fadff 0x29e2b037 0xe1819 0xdb64f 0x25f64de1 0x25f64d99 0x25f64e8d 0x25e261ef 0x25edf04f 0xa77cab 0xa7f835 0x25e171e3 0x258415f9 0x25e170cb 0x25e16f95 0x25e16e29 0x258f1257 0x258f0e47 0x258ef1af 0x25841bb9 0x258419ad 0x26abbaf9 0x29b2dfb5 0xe3ea9 0x254f4873)
libc++abi.dylib: terminating with uncaught exception of type NSException
**
If you're using segueWithIdentifier then you need to already have the segue built in Storyboard and labeled correctly as "showTypeView". Otherwise you should use a navigation controller to push a view controller or use self presentViewController to show a modal view controller.
EDIT:
Building off of Larme's comment, you can build a delegate like this:
// In your class.h file
#property (weak, nonatomic)id<SegueDelegate> delegate;
// In class.m file
LoginViewController *showView = [LoginViewController new];
self.delegate = showView;
[self.delegate segue];
// In LoginViewController.h
#protocol SegueDelegate
-(void)segue;
#end
#interface LoginViewController: UIViewController <SegueDelegate>
-(void)segue;
#end
// In LoginViewController.m
#implementation LoginViewController
-(void)segue
{
[self performSegueWithIdentifier:#"showTypeView" sender:nil];
}
#end
There are 3 behaviors in my method, I'm pretty sure animationOptions is the one causing bug. AnimationOptions is only used to ban rotation.If i delete this behavior,my code work fine.
Here is my bug.Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil’
After I add a exception breakpoint, the breakpoint stay at this line:
[self addChildBehavior:self.animationOptions];
If i delete this line, my code work fine.
But how can i fix this bug, I can not find where is this line mistake
Here is my DropitBehavior.m
#import "DropitBehavior.h"
#interface DropitBehavior()
#property(strong,nonatomic) UIGravityBehavior *gravity;
#property(strong,nonatomic) UICollisionBehavior *collider;
#property(strong,nonatomic) UIDynamicItemBehavior *animationOptions;
#end
#implementation DropitBehavior
-(UIGravityBehavior *)gravity
{
if (!_gravity) {
_gravity=[[UIGravityBehavior alloc]init];
_gravity.magnitude=0.90;
}
return _gravity;
}
-(UICollisionBehavior *)collider
{
if (!_collider) {
_collider=[[UICollisionBehavior alloc]init];
_collider.translatesReferenceBoundsIntoBoundary=YES;
}
return _collider;
}
-(UIDynamicItemBehavior *)animationOptions
{
if (_animationOptions) {
_animationOptions=[[UIDynamicItemBehavior alloc]init];
_animationOptions.allowsRotation=NO;
}
return _animationOptions;
}
-(void)additem:(id <UIDynamicItem>)item
{
[self.gravity addItem:item];
[self.collider addItem:item];
[self.animationOptions addItem:item];
}
-(void)removeitem:(id <UIDynamicItem>)item
{
[self.gravity removeItem:item];
[self.collider removeItem:item];
[self.animationOptions removeItem:item];
}
-(instancetype)init
{
self=[super init];
[self addChildBehavior:self.gravity];
[self addChildBehavior:self.collider];
[self addChildBehavior:self.animationOptions];
return self;
}
#end
a NSMutable array doesn't accept a "nil" to be added to itself
"self.animationOptions" will call the
-(UIDynamicItemBehavior *)animationOptions
method and the method will return only "nil" all the time.
-(UIDynamicItemBehavior *)animationOptions
{
if (_animationOptions) {
_animationOptions=[[UIDynamicItemBehavior alloc]init];
your logic in this piece of code doesn't allow the system to construct "_animationOptions" object.
if (!_animationOptions)
{
..code..
}
would help
My task is to create custom UIAlertView with multiline text input field and everything works pretty much well up to the point where I need to do some actions if dismiss button was tapped. As example I'm using: http://iphonedevelopment.blogspot.co.uk/2010/05/custom-alert-views.html
I have created very simple popup for testing purpose. Basically it's UIViewController xib with single button in it. The main class is demonstrated below:
#import "testViewController.h"
#interface testViewController ()
#end
#implementation testViewController
- (id)init
{
self = [super initWithNibName:#"testViewController" bundle:nil];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)showInView:(UIView *)view
{
[view addSubview:[self view]];
[[self view] setFrame: [view bounds]];
[[self view] setCenter:[view center]];
}
- (IBAction)onTap:(id)sender {
NSLog(#"All OK");
}
#end
then in root UIViewController I'm calling my custom alert:
- (IBAction)showAlert:(id)sender
{
dispatch_async(dispatch_get_main_queue(), ^{
testViewController *alert = [[testViewController alloc] init];
[alert showInView:[self view]];
});
}
So far I have tried Main thread or global queue or even synchronous dispatch, but everything ends up with break on:
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); <-- Thread 1:EXC_BAD_ACCESS (code=1, address=0xa000000c)
}
}
tried to add observer for the button but still no go..
Any help is much appreciated
Here what happing is "if you want to add one viewcontroller view to other viewcontroller's view then after adding of views you should convey to the compiler that second view controller is going to be child to the first"
i.e pre intimation of parent to child relationship has to be done.
now just modify your showAlert method with the following . it is working 100%.
- (IBAction)showAlert:(id)sender {
dispatch_async(dispatch_get_main_queue(), ^{
testViewController *alert = [[testViewController alloc] init];
[alert showInView:[self view]];
[self addChildViewController:alert];
[alert didMoveToParentViewController:self];
});
}
Check if your UIButton is assigned multiple IBoutlets or multiple IBActions. This a common issue which happens without our notice sometimes.
It turns out that my testViewController was released by ARC before I tap the button
I create a CustomView:UIView with XIB, load and addObserver for a NSInteger property like that:
//CustomView.h
#interface CustomView : UIView
#property (nonatomic) NSInteger inputStateControl;
#end
//CustomView.m
static void *kInputStateControlObservingContext = &kInputStateControlObservingContext;
#implementation CustomView
- (id)init
{
self = [super init];
if (self) {
// Initialization code
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:nil];
self = [nib objectAtIndex:0];
//
[self commonInit];
}
return self;
}
-(void)commonInit{
[self addObserver:self forKeyPath:#"inputStateControl" options:NSKeyValueObservingOptionOld context:kInputStateControlObservingContext];
}
#pragma mark Observer
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ( context == kInputStateControlObservingContext ) {
NSInteger oldState = [[change objectForKey:NSKeyValueChangeOldKey] integerValue];
if ( oldState != self.inputStateControl ) {
NSLog(#"CONTEXT change %i to %i",oldState,self.inputStateControl);
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
-(void)dealloc{
[self removeObserver:self forKeyPath:#"inputStateControl"];
// [self removeObserver:self forKeyPath:#"inputStateControl" context:kInputStateControlObservingContext];
}
#end
Everything work OK if I comment out removeObserver in dealloc, here is the log:
CONTEXT change 0 to 2
But when removeObserver, App crash:
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <Keyboard 0x6a8bcc0> for the key path "inputStateControl" from <Keyboard 0x6a8bcc0> because it is not registered as an observer.'
No crash when comment load CustomView.xib but nothing to do without XIB.
What's wrong in my code?
How to add and removeObserver for an NSInteger property inside CustomView with Custom Xib?
Thanks in advance!
*EDIT: I add my code to make my question clear. Please help!
https://github.com/lequysang/github_zip/blob/master/CustomViewKVO.zip
Here's what's happening - in your viewDidLoad method, you call [[CustomView alloc] init]. This creates a new CustomView instance, and calls init on it. However, in init, you load a new instance from the nib and replace self with the one from the nib. This causes the instance that you created from alloc and set up with the self = [super init]; to be deallocated as there are no more strong references to it. Since this instance is deallocated before calling commonInit, it never observes its own properties so removing itself as an observer causes the exception.
One way to fix this would be to just load the view directly from the nib in your view controller, or create a class method on CustomView
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:nil options:nil];
CustomView *customView = topLevelObjects[0];
If you do take that approach, discard you init implementation and replace it with an initWithCoder: that does this:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
_inputStateControl = 0;
[self commonInit];
}
return self;
}
The reason for implementing initWithCoder: is that it will be called automatically when you load the view from the nib. You just have to implement it and you will be able to do the setup that you are already doing in init. Also make sure your dealloc is implemented like so:
-(void)dealloc{
[self removeObserver:self forKeyPath:#"inputStateControl" context:kInputStateControlObservingContext];
}
I don't know exactly why what you're doing isn't working, but having an object observe itself like this strikes me as a bad idea. You should just implement your inputStateControl's setter explicitly (setInputStateControl) and do your logging and whatever other side effects you want in that setter method.
While not an ideal solution by any means, surrounding the remove with a try-catch block will resolve your issue. If in fact the observer is not registered, ignoring an exception during removing it is safe. The main risk is whatever assumption your app is relying on that it IS registered.
Not sure why you're facing the problem.The most short cut way i do is by setting the custom observer to 'nil' in the dealloc ;) ,but in your case to use that shortcut way also you need to add the obeserver in some other way around.
Ok at least i can tell you is,in your dealloc,
-(void)dealloc{
[[NSNotificationCenter default center] removeObserver: self];
[self removeObserver:self forKeyPath:#"inputStateControl"];
//OR
//If you had create a observer called "temp",then easy way to remove the observer is temp=nil;
}
If you're still hanging in,put the #try #catch blocks for the temporary solution,note that its not going to remove the observer ;)...
Not the perfect the answer you were looking for,but its just the way i think...Happy coding :-)