iPhone应用程序崩溃,出现NSUnknownKeyException setValue:forUndefinedKey:错误。

19

我正在编写我的第一个iPhone应用程序,所以我还没有找出很多调试方面的问题。 基本上,我的应用程序会显示一张图片,触摸后会播放短暂的声音。 在XCode中编译和构建项目时,一切都成功构建,但在iPhone模拟器中运行应用程序时,它会崩溃。

我收到以下错误:

Application Specific Information:
iPhone Simulator 1.0 (70), iPhone OS 2.0 (5A331)
*** Terminating app due to uncaught exception 'NSUnknownKeyException', 
reason: '[<UIView 0x34efd0> setValue:forUndefinedKey:]: this class is not key value 
coding-compliant for the key kramerImage.'

这里的kramerImage是我用作背景的图片。

我不确定NSUnknownKeyException是什么意思,也不知道为什么该类不符合键值编码的要求。

8个回答

22
这并不是特定于iPhone的 - 在常规Cocoa中会发生相同的事情。
NSUnknownKeyException是使用键值编码访问对象没有的键时常见的错误。
大多数Cocoa对象的属性可以直接访问:
[@"hello world" length]    // Objective-C 1.0
@"hello world".length      // Objective-C 2.0

或者通过键值编码:
[@"hello world" valueForKey:@"length"]

如果我使用以下行,会得到NSUnknownKeyException异常:
[@"hello world" valueForKey:@"purpleMonkeyDishwasher"]

因为NSString没有名为'purpleMonkeyDishwasher'的属性(键)。
你的代码中有些地方试图在一个UIView上设置'kramerImage'这个键的值,而(显然)该视图不支持该键。如果你正在使用Interface Builder,则可能是nib文件中的某些内容。
找到使用'kramerImage'的地方,并从那里尝试追踪它。

2
我遇到了这个错误,它与Interface Builder有关,但我无法弄清楚如何修复它。 - bentford
1
谢谢,又浪费了三个小时,问题终于解决了。 :) - Toby Allen
我在将文件从一个项目复制到另一个项目时遇到了这个问题。我的xib引用了错误的类名。这个答案为我提供了足够的信息,让我恍然大悟,非常感谢。 - Grumdrig
感谢您的详细解释,但由于我仍然感到困惑,没有太大帮助。我只是为 TableCellView 加载了一个 bundle,但在任何操作之前就出现了所有内容崩溃的情况: http://pastebin.com/QuR29q6B - Zennichimaro

10

当你重命名一个视图时,不要忘记删除文件所有者上的引用。否则可能会引发此错误。


1
+1 这种情况我也遇到过。我给我的 MKMapView 重命名了变量,结果突然间就出现了 NSUknownUknownKeyException 异常。 - ladookie
Storyboard中有一个链接到空白的按钮,导致了KeyValue错误。这解决了我的问题。谢谢! - Michael Ozeryansky

8
这里有一个可能会出现错误的情况,以及如何修复它。当加载一个仅包含自定义TableViewCell的nib时,我遇到了这个问题。我使用IB构建了一个xib,其中只包含文件所有者、第一响应者和TableViewCell。TableViewCell只包含4个UILabel,与一个名为rootCell的类中的4个IBOutlet UILabel相匹配。我将TableViewCell的类更改为rootCell。一切都正常工作,直到我进行了几次更改,突然之间在从nib实例化类后就会出现setValue:forUndefinedKey:的错误:
    NSArray * nib = [[NSBundle mainBundle] loadNibNamed:@"rootCell-iPad" owner:self options:nil];

    cell = [nib objectAtIndex:0];

它在第一行失败,当nib尝试加载时。过了一会儿,我注意到它试图将IBOutlet标签与根控制器匹配,而不是rootCell类!这就是我的提示。我做错的是无意中将文件所有者更改为rootCell类。当我将其改回NSObject时,它就不会在加载时尝试与委托(rootController)匹配。因此,如果您正在执行上述操作,请将File's Owner设置为NSObject,但将UITableCell设置为所需的类。

+1 并且提醒自己和其他总是忘记的人:在使用loadNibNamed:owner:options:时,文件所有者应该是NSObject,主视图应该是你的类类型,并且所有插座应该连接到视图,而不是文件所有者。 - Echelon
谢谢Owen,我也遇到了完全相同的情况。按照描述解决了。非常感谢! - Khiet

2

今天我遇到了同样的问题。在我的导航控制器中,视图控制器没有指定正确的类。如果你在界面构建器中未指定正确的视图类,这种情况会经常发生。

你也会遇到无效选择器问题。始终检查你的界面构建器类和连接!


谢谢。我在IB中正确指定了类,但是我的控制器和我在initWithNibName:中指定的nib之间存在不匹配 - 我应该被取消复制粘贴的权限。 - masty
回到iOS道场,练习你的复制+粘贴技巧。 - gonzobrains

2

我遇到了这种情况,尽管找到并删除了所有变量的实例,但我的应用程序仍然崩溃了。发生了什么事呢?我从XIB中创建了一个文本字段的另一个变量实例,并将其放入了viewController.h中,但后来意识到它不再需要,于是将其删除。结果发现我的程序仍在尝试使用它,所以如果这种情况发生在其他地方,请进入你的XIB,右键单击按钮或文本字段等,删除任何多余的未使用变量即可。


2
这是我解决的方法,在Interface Builder中右键单击视图控制器,缺少的输出口或操作方法上应该有一个惊叹号。找到并删除所有引用,问题就解决了。
这是因为我在.m文件中删除了操作方法。

0

看起来你正在做

@interface MyFirstIphoneAppViewController : UIViewController<> {
    UIImageView *InitialkramerImage;
}
@property(nonatomic,retain) IBOutlet UIImageView *InitialkramerImage;

然后,在合成图像视图之后,当您在 Interface Builder 中打开“MyFirstIphoneAppViewController.xib”时,您需要从工具(菜单)/库中获取一个图像视图,并将该出口链接到“MyFirstIphoneAppViewController.xib”的“Files Owner”中的“InitialkramerImage”。然后,保存项目。但在此之后,您可能会更改出口变量“InitialkramerImage”的名称为“kramerImage”。所以,在这样做之后,
@interface MyFirstIphoneAppViewController : UIViewController<> {
    UIImageView *kramerImage;
}
@property(nonatomic,retain) IBOutlet UIImageView *kramerImage;

在运行项目并保存时,“MyFirstIphoneAppViewController.xib”中不存在“InitialkramerImage”的出口。因此,当您运行项目时,将没有从ImageView到“kramerImage”的出口引用。

“为了显示视图,UIViewController将尝试查找不存在的‘InitialkramerImage’出口。”

因此,它会抛出“NSUnknownKeyException”异常。

您可以通过打开nib(.xib)文件,然后右键单击该文件的“Files Owner”来检查缺少的出口。


0

如果你在其他地方编写了这段代码并且有一个zip/压缩文件,请尝试重新提取它。我不知道为什么,但我觉得这可能是一个提取问题。

或者您可以尝试将IBOutlet更改为kramerImage,并在NIB中重新绑定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接