由于未捕获的异常"NSUnknownKeyException"而终止应用程序:iOS应用程序崩溃 [英] Terminating app due to uncaught exception 'NSUnknownKeyException' : iOS app crash

查看:73
本文介绍了由于未捕获的异常"NSUnknownKeyException"而终止应用程序:iOS应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是从事iPhone应用程序的初学者.我想知道是否有人可以帮助解决我的应用程序中的错误.在XCode上编程时,我发现我的应用程序在添加更多代码后突然崩溃.输出面板显示以下错误:

*由于未捕获的异常'NSUnknownKeyException'而终止应用程序,原因:'[setValue:forUndefinedKey:]:此类不适用于键播放的键值编码. * :第一个引发调用堆栈: (0x1c91012 0x10cee7e 0x1d19fb1 0xb7ae41 0xafc5f8 0xafc0e7 0xb26b58 0x230019 0x10e2663 0x1c8c45a 0x22eb1c 0xf37e7 0xf3dc8 0xf3ff8 0xf4232 0x433d5 0x4376f 0x43905 0x8eceab6 0x4c917 0x1096c 0x1194b 0x22cb5 0x23beb 0x15698 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962 0x1c37bb6 0x1c36f44 0x1c36e1b 0x1117a 0x12ffc 0x222d 0x2155) libc ++ abi.dylib:终止调用引发异常 (lldb)

应用终止时显示的代码如下

#import <UIKit/UIKit.h>
#import "CIAAppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([CIAAppDelegate class]));
    }
}

我的ViewController.h显示:

#import <UIKit/UIKit.h>

@interface CIAViewController : UIViewController {
    IBOutlet UILabel *cruzia;
    IBOutlet UILabel *textarea;
    IBOutlet UIButton *playbtn;
    IBOutlet UIButton *tutorialbtn;
    IBOutlet UIButton *optionsbtn;
    IBOutlet UIButton *trainingbtn;
    IBOutlet UIButton *back;
}

-(IBAction)press;
-(IBAction)press2;
-(IBAction)press3;
-(IBAction)press4;
-(IBAction)press5;

我的ViewController.m也显示

#import "CIAViewController.h"

@interface CIAViewController ()
@end

@implementation CIAViewController

-(IBAction)press {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Play";
    textarea.text = @"Hello! You are playing the game of Cruzia!";
}

-(IBAction)press2 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Tutorial";
    textarea.text = @"Welcome! You are watching the Cruzia tutorial!";
}

-(IBAction)press3 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Options";
    textarea.text = @"You are now in the Options screen. You can edit the settings of the game!";
}

-(IBAction)press4 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Training";
    textarea.text = @"This is the training area. You can improve your Cruzia skills here!";
}

-(IBAction)press5 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 0;
    tutorialbtn.hidden = 0;
    optionsbtn.hidden = 0;
    trainingbtn.hidden = 0;
    back.hidden = 1;
    cruzia.text = @"Cruzia";
}


- (void)viewDidLoad
{
    textarea.hidden = 1;
    playbtn.hidden = 0;
    tutorialbtn.hidden = 0;
    optionsbtn.hidden = 0;
    trainingbtn.hidden = 0;
    back.hidden = 1;
    cruzia.text = @"Cruzia";
    [super viewDidLoad];
}

@end

很抱歉浪费您的时间,但很长一段时间以来我都遇到此错误,如果您有解决方案,希望得到它.

解决方案

问题所在:

在运行时,您的视图控制器将从其XIB/Storyboard反序列化.在此过程中,它将读取IB文件中的所有对象,并开始使用NSCoder实例化它们.在实例化视图中的对象时,将读取情节提要中的IBOutletIBAction连接,并开始将水合对象分配给在 design 时连接的那些属性,以便您可以在运行时以编程方式访问它们.但这是踢球者:如果您有一个指向不存在的属性的连接,则将引发此异常,因为它被告知那里确实不存在该属性.

正在发生的事情是您的Storyboard/XIB希望您的类具有名为play的属性.如界面所示,您没有名为那个的属性.但是我怀疑您曾经使用过,但是将其重命名为playbtn.

这是什么意思

此类不适用于键播放的键值编码

这意味着它试图在幕后做这样的事情:

[self setValue:button forKey:@"play"]

有关键/值编码和序列化的其他启示,请抓住舒适的椅子,然后阅读

My ViewController.h shows:

#import <UIKit/UIKit.h>

@interface CIAViewController : UIViewController {
    IBOutlet UILabel *cruzia;
    IBOutlet UILabel *textarea;
    IBOutlet UIButton *playbtn;
    IBOutlet UIButton *tutorialbtn;
    IBOutlet UIButton *optionsbtn;
    IBOutlet UIButton *trainingbtn;
    IBOutlet UIButton *back;
}

-(IBAction)press;
-(IBAction)press2;
-(IBAction)press3;
-(IBAction)press4;
-(IBAction)press5;

Also my ViewController.m shows

#import "CIAViewController.h"

@interface CIAViewController ()
@end

@implementation CIAViewController

-(IBAction)press {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Play";
    textarea.text = @"Hello! You are playing the game of Cruzia!";
}

-(IBAction)press2 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Tutorial";
    textarea.text = @"Welcome! You are watching the Cruzia tutorial!";
}

-(IBAction)press3 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Options";
    textarea.text = @"You are now in the Options screen. You can edit the settings of the game!";
}

-(IBAction)press4 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 1;
    tutorialbtn.hidden = 1;
    optionsbtn.hidden = 1;
    trainingbtn.hidden = 1;
    back.hidden = 0;
    cruzia.text = @"Training";
    textarea.text = @"This is the training area. You can improve your Cruzia skills here!";
}

-(IBAction)press5 {
    cruzia.hidden = 0;
    textarea.hidden = 0;
    playbtn.hidden = 0;
    tutorialbtn.hidden = 0;
    optionsbtn.hidden = 0;
    trainingbtn.hidden = 0;
    back.hidden = 1;
    cruzia.text = @"Cruzia";
}


- (void)viewDidLoad
{
    textarea.hidden = 1;
    playbtn.hidden = 0;
    tutorialbtn.hidden = 0;
    optionsbtn.hidden = 0;
    trainingbtn.hidden = 0;
    back.hidden = 1;
    cruzia.text = @"Cruzia";
    [super viewDidLoad];
}

@end

I am sorry to waste your time but I have had this error for a long time and would like it if you had a solution.

What The Problem Is:

At runtime your view controller is going to get deserialized from its XIB/Storyboard. During this process, it's going to read all the objects that are in your IB files and start instantiating them with an NSCoder. As it is instantiating those objects in your view, it's going to read the IBOutlet and IBAction connections in your storyboard and start assigning the hydrated objects to those properties that were connected at design time so that you have programmatic access to them at run time. But here's the kicker: If you have a connection that points to a property that doesn't exist, then this exception will be thrown because it was told a property was there that really isn't.

What's happening is that your Storyboard/XIB is expecting your class to have a property called play. As your interface shows, you do not have a property called that. I suspect though, that you used to, but renamed it playbtn.

This is what is meant by

this class is not key value coding-compliant for the key play

It means it tried to do something like this under the covers:

[self setValue:button forKey:@"play"]

For additional enlightenment about Key/Value Coding and serialization, grab a comfy chair and read Key Value Coding Programming Guide and Archives and Serializations Programming Guide

How To Fix It:

In Interface Builder, right click on your view controller and see the list of connections:

See how there is a connection for the property play and it has a little yellow triangle next to it? This is Interface Builder trying to warn you that you have a connection set there, but the header isn't showing that there is an IBOutlet of that name.

All you need to do is click that little x to break the connection to the missing property.

How To Prevent This In The Future

Anytime you change a property in your code, you'll need to make sure that you break any associated connection in Interface Builder.

这篇关于由于未捕获的异常"NSUnknownKeyException"而终止应用程序:iOS应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆