zeroconfig
zeroconfig

Reputation: 1

iOS NSInvalidArgumentException, unrecognized selector sent to instance

i'm a newbie to iOS, working through the tutorials. Now, i have this piece of code:

- (void)viewWillAppear:(BOOL)animated
{
    // [super viewWillAppear:animated];
    if(self.firstName)
    {
        NSLog(@"%@",self.firstName);
        self.textFieldFirstName.text = self.firstName;
    }
}

Firstly, as above, i had to comment out the call to super - the app did not want to start. Secondly: the assignement self.textFieldFirstName.text = self.firstName; crashes the app with SIGABORT and output:

2014-10-13 11:50:19.631 PersonalStoryboard[1451:60b] firstName = John
2014-10-13 11:50:19.636 PersonalStoryboard[1451:60b] John
2014-10-13 11:50:19.636 PersonalStoryboard[1451:60b] -[UIView setText:]: unrecognized selector sent to instance 0x8f97470
2014-10-13 11:50:19.639 PersonalStoryboard[1451:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setText:]: unrecognized selector sent to instance 0x8f97470'
*** First throw call stack:

Why? Thanks in advance.


Thanks folks. File 1:

//

#import "FirstNameEditViewController.h"

@interface FirstNameEditViewController ()
@property (strong, nonatomic) IBOutlet UITextField *textFieldFirstName;
@end

@implementation FirstNameEditViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated
{
    // [super viewWillAppear:<#animated#>];
    if(self.firstName)
    {
        NSLog(@"%@",self.firstName);
        self.textFieldFirstName.text = self.firstName;
    }
}

@end

File 2:

#define LogPretty NSLog(@"LogPretty:%s %d %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
#import "PersonalDetailViewController.h"
#import "FirstNameEditViewController.h"
#import "Person.h"

@interface PersonalDetailViewController ()

  @property (strong, nonatomic) IBOutlet UIButton *buttonFirstName;
  @property (strong, nonatomic) IBOutlet UIButton *buttonName;
  @property (strong, nonatomic) IBOutlet UIButton *buttonAge;
  @property (strong, nonatomic) IBOutlet UIButton *buttonJob;
  @property (strong, nonatomic) IBOutlet UIButton *buttonSalary;

@end

@implementation PersonalDetailViewController
{
    Person *person;
 }
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    person = [[Person alloc] init];
    [self showPerson];
}

- (void)showPerson
{
    LogPretty
    /*
     IT CRASHES HERE !!!

    [self.buttonFirstName setTitle:person.firstName forState:UIControlStateNormal];
    [self.buttonName setTitle:person.name forState:UIControlStateNormal];
    [self.buttonJob setTitle:person.job forState:UIControlStateNormal];
    [self.buttonAge setTitle:person.age forState:UIControlStateNormal];
    [self.buttonSalary setTitle:person.salary forState:UIControlStateNormal];
    */
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)buttonFirstNameTouched:(id)sender {
    [self performSegueWithIdentifier:@"firstNameEditSegue" sender:(self)];
}
- (IBAction)buttonNameTouched:(id)sender {
}
- (IBAction)buttonAgeTouched:(id)sender {
}
- (IBAction)buttonJobTouched:(id)sender {
}
- (IBAction)buttonSalaryTouched:(id)sender {
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"identifier = %@",segue.identifier);

    if([segue.identifier isEqualToString:@"firstNameEditSegue"])
    {
        NSLog(@"firstName = %@",person.firstName);
        FirstNameEditViewController *editController = segue.destinationViewController;
        editController.firstName = person.firstName;
    }
}
@end

And finally the Person:

#define LogPretty NSLog(@"%s %d %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
#import "Person.h"

  @implementation Person

- (id) init
{
    LogPretty
    self = [super init];
    if(self)
    {
        self.firstName = @"John";
        self.name = @"Brown";
        self.job = @"Developer";
        self.age = 35;
        self.salary = 35000;
    }
    return self;
}
@end

i'll be greatfull for help

Upvotes: 0

Views: 1614

Answers (3)

zeroconfig
zeroconfig

Reputation: 1

OK folks, the problem is solved. The tutorial read, i have to drag the line from the UI element (TextInput or Button) to the code to implement it there. In fact, it should read: MARK IT FIRST, then drag the line, otherwise the UIView will be passed.

Simple for professionals, damn hard to detect for beginners. Anyway, thanks a lot.

Upvotes: 0

nburk
nburk

Reputation: 22751

Ok, first, the call to super is important, if you have to comment it out to make your code work there must be something wrong somewhere else as well. It is important because it is responsible to perform operations in the superclass of your class, which is UIViewController. This method is part of the lifecycle of a UIViewController.

Your actual problem comes from the fact that you want to call the method setText: on an object of type UIView, this is indicated by the message: -[UIView setText:]: unrecognized selector sent to instance 0x8f97470. If you take a look at the documentation of the UIView class, you will see that it does not expose a method called setText: (or rather, it doesn't have a text property and along with that a setter method for it). This is why the app crashes.

I assume you want to perform this operation on either a UILabel or a UITextField. What I can also imagine is that you are actually already using either of these classes, but it doesn't work because you commented you viewWillAppear. In that case you should show more code and you r storyboard setup, otherwise it will be difficult to find your problem or give you further guidance.

Last short note, this kind of initialaztion is best being done in viewDidLoad not viewWillAppear.

Upvotes: 1

Oleg Gordiichuk
Oleg Gordiichuk

Reputation: 15512

Do not comment [super viewWillAppear:animated];

- (void)viewWillAppear:(BOOL)animated
{
     [super viewWillAppear:animated];
    if(self.firstName)
    {
        NSLog(@"%@",self.firstName);
        self.textFieldFirstName.text = self.firstName;
    }
}

To work with UIElements it is better to use:

- (void)viewDidLoad
{
    [super viewDidLoad];
}

Than what type is self.firstName is it id or NSString?

If it is id of the uitextview you should use .text property of that.

Upvotes: 0

Related Questions