0

I'm a noob to iOS development, so am following the HelloWorld tutorial here. I've got to the stage where I'm testing the app after adding the button, text field and label. I have followed the tutorial to the letter as far as I'm aware and I'm getting this error when I run the app:

2013-07-13 15:26:39.629 HelloWorld[1304:11303] * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<HelloWorldViewController 0x7566000> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key label.' * First throw call stack: (0x1c90012 0x10cde7e 0x1d18fb1 0xb79e41 0xafb5f8 0xafb0e7 0xb25b58 0x22f019 0x10e1663 0x1c8b45a 0x22db1c 0xf27e7 0xf2dc8 0xf2ff8 0xf3232 0x423d5 0x4276f 0x42905 0x4b917 0xf96c 0x1094b 0x21cb5 0x22beb 0x14698 0x1bebdf9 0x1c13f3f 0x1c1396f 0x1c36734 0x1c35f44 0x1c35e1b 0x1017a 0x11ffc 0x1f9d 0x1ec5) libc++abi.dylib: terminate called throwing an exception

The code generated in HelloWorldViewController.m is:

#import "HelloWorldViewController.h"

@interface HelloWorldViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UITextField *textField;
- (IBAction)changeGreeting:(id)sender;

@end

@implementation HelloWorldViewController

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

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)changeGreeting:(id)sender {
}
@end

And in HelloWorldViewController.h:

#import <UIKit/UIKit.h>

@interface HelloWorldViewController : UIViewController

@end

I tried using this answer but I can't see an XIB file (I think because I'm using a Storyboard?) and I can't see any obvious discrepancies in the VC.

Please help.

Community
  • 1
  • 1
Ed King
  • 1,833
  • 1
  • 15
  • 32
  • possible duplicate of [This class is not key value coding-compliant for the key](http://stackoverflow.com/questions/3088059/this-class-is-not-key-value-coding-compliant-for-the-key) – jtbandes Aug 01 '15 at 21:54

2 Answers2

0

A storyboard is a single file that encapsulates a collection of XIB files. Each "scene" in a storyboard represents what would otherwise be a single XIB file.

In the storyboard...

(1) Select the View Controller in the relevant scene.
(2) Open the Identity Inspector (third tab in the right-hand Utilities pane). Check that the view controller's class is correctly set to HelloWorldViewController.
(3) check that the View Controller's IBOutlets are correctly wired up to the correct views. (Ctrl-click on each view and check it's settings in the HUD).

'Wiring up' entails CTRL-dragging from your viewController to the relevant view in your storyboard scene. A list will appear of appropriate IBOutlet properties to select.

These properties can be placed either in the interface declaration in the .h file or in a class extension in the .m file.

An interface declared as @interface (in the .h file) is public; A class extension declared as @interface() (usually in the .m file) is private to the class (although nothing is completely private in Obj-C). Class extensions are useful for declaring private properties, or properties that are publicly readonly and privately readwrite. See the apple docs. They used to be good for declaring private methods, but now this is redundant: methods only need declaring if we want to make them public.

A good rule of thumb is wherever possible, keep your declarations in the class extension and out of the .h file. These days this should only apply to properties as method declarations are not required unless making them public.

You mentioned that you fixed your problem by moving your property declarations from the class extension to the public interface. This is puzzling, as both locations are normally acceptable for this use.

foundry
  • 31,615
  • 9
  • 90
  • 125
  • (2) Is ok. (3) Not quite sure what I'm looking for here - it doesn't look like anything's connected? – Ed King Jul 13 '13 at 16:27
  • Ok, I think I've fixed it but I don't really understand how. There's an `@interface` in the `.h` and `.m` file. I moved the `@property` attributes to the header and now I don't get the error? Why are there two interfaces with different syntax? I'm new to Objective-C too, so I'm probably getting confused because of this! – Ed King Jul 13 '13 at 17:02
  • Sorry for the delayed reply. I couldn't get things to work so I started the tutorial again and have got to the same point. The actions and outlets are in the class extension as instructed in the tutorial. I achieved these with Ctrl-dragging to the class extension. The problem seems to be something to do with naming. Without doing anything else, the Connections Inspector shows a `!` next to the `textField` and `label` outlets, saying *"HelloWorldViewController does not have an outlet named [label | textField]"*. Any ideas? – Ed King Jul 15 '13 at 21:45
  • It seems the Apple developer site updated the tutorial. They now suggest Ctrl-clicking your outlets into the header file, not the implementation file, and I can now complete it. – Ed King Jul 23 '13 at 09:08
0

I removed all referencing outlets and actions which you can see at connection indicator while selecting objects one by one at storyboard workspace, and deleted some codes added automatically by xcode.

And then I made them by following tutorials again. finally it worked fine.

Ben
  • 51,770
  • 36
  • 127
  • 149