0

I create a simple iPhone app with xib file, and add one button to the view. create a IBOutlet to connect with it. each time, I launch it, it will crash. the full error message is as below: 2014-05-03 08:10:19.742 test[1435:a0b] * Terminating app due to uncaught exception

'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key txtBtn.'

There are many people hitting this question, After reviewing the answers, I think my problem is different one. code is as below.

#import <UIKit/UIKit.h>

@interface XIBViewController : UIViewController
{
    UIButton *txtBtn;
}
@property (nonatomic, retain) IBOutlet UIButton *txtBtn;
@end

source of creating this view controller:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    UIViewController *controller = [[UIViewController alloc] initWithNibName:@"XIBViewController" bundle:[NSBundle mainBundle]];
    self.window.rootViewController = controller;

    return YES;
}

source of xib file is

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="12F45" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="XIBViewController">
            <connections>
                <outlet property="txtBtn" destination="kvg-9r-q01" id="Xtc-tf-xGb"/>
                <outlet property="view" destination="1" id="l1j-Dp-A65"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="1">
            <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kvg-9r-q01">
                    <rect key="frame" x="103" y="158" width="79" height="30"/>
                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                    <state key="normal" title="Hello World">
                        <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                    </state>
                </button>
            </subviews>
            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
            <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
        </view>
    </objects>
</document>
  • 1
    What's the whole error message? It should say *which* key it's complaining about. – Phillip Mills May 03 '14 at 15:19
  • update the post with more info. Thanks. – user3599379 May 03 '14 at 15:21
  • This error is usually because you mucked up a XIB-to-class mapping -- you linked the XIB to a class that doesn't contain a `txtBtn` method. (Is the compiler warning you that you didn't synthesize txtBtn?) – Hot Licks May 03 '14 at 15:26
  • I've posted an answer that should solve the issue... but out of curiosity, since you're obviously starting a new project and not maintaining legacy code, why aren't you using storyboards? – nhgrif May 03 '14 at 15:27
  • for learning new stuff. – user3599379 May 03 '14 at 15:46
  • That's not really a good excuse unless you're planning on maintaining some legacy code sometime soon. "I'm doing method A to learn new things even though the only way I'd ever need to use method A is to maintain legacy code." Do you have some legacy code you need to maintain? And is it too big to convert to a storyboard project? – nhgrif May 03 '14 at 15:51

1 Answers1

1

You've created a UIViewController object, which doesn't have a txtBtn property.

You need to change from this line:

UIViewController *controller = [[UIViewController alloc] initWithNibName:@"XIBViewController" bundle:[NSBundle mainBundle]];

To this:

XIBViewController *controller = [[XIBViewController alloc] initWithNibName:@"XIBViewController" bundle:[NSBundle mainBundle]];

You'll also need to #import XIBViewContoller.h in your AppDelegate.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
  • In the xib file, I already specify the file owner is XIBViewController, why system can not return a XIBViewController object? then I do not import that header file. – user3599379 May 03 '14 at 15:47
  • Because YOUR code is telling it to create an object of type `UIViewController`, and it's view should be created by the nib name you gave it. Specifying the file owner is merely done so that you can hook up the outlets in the xib file to the appropriate class. – nhgrif May 03 '14 at 15:49