未捕获的异常:此类不符合键值编码兼容性。

60
我正在跟随一份名为“Swift教程:iOS NSFileManager持久化数据”的教程,但在大约29分钟后遇到了错误。当我尝试在iOS模拟器上运行它时,我收到以下错误:

终止应用程序由于未捕获的异常'NSUnknownKeyException',原因:'[setValue:forUndefinedKey:]:此类不符合关键值编码-compliant for the key theLoadMethod.'

显然根据错误,我认为问题出在我的 theLoadMethod上。下面是我在这个项目中作为 ViewController 写的全部代码:

let theDocumentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let theFileName     = "/theUserFile.txt"
let thePath         = theDocumentsFolder.stringByAppendingString(theFileName)


class ViewController: UIViewController {

@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var lastNameTextField: UITextField!
@IBOutlet weak var ageTextField: UITextField!

@IBOutlet weak var theLabel: UILabel!

// The save method
@IBAction func theSaveMethod(sender: AnyObject) {
    var name        = nameTextField.text
    var lastName    = lastNameTextField.text
    var age         = ageTextField.text

    var theString   =   "The user's information is: \(name), \(lastName), \(age)"

    let theFileManager = NSFileManager.defaultManager()

    if !theFileManager.fileExistsAtPath(thePath) {

        var writeError:NSError?
        let fileToBeWritten = theString.writeToFile(thePath, atomically: true, encoding: NSUTF8StringEncoding, error: &writeError)

        if writeError == nil {
            println("No errors. Added: \(theString)")
        } else {
            println("Encountered an error. Error is: \(writeError)")
        }

    } else {
        println("File already exists")
    }

    nameTextField.resignFirstResponder()
    lastNameTextField.resignFirstResponder()
    ageTextField.resignFirstResponder()
}

@IBAction func theLoadMethod(sender: AnyObject) {
    let infoFromFile:String = String.stringWithContentsOfFile(thePath, encoding: NSUTF8StringEncoding, error: nil)!

    theLabel.text = infoFromFile
}

我有做错的地方吗?据我所知,我所有的iOS屏幕元素都已经正确命名和链接了。


1
这通常是由于你的故事板链接到一个不存在的属性引起的。仔细检查故事板中对象的所有链接。 - Paulw11
@Paulw11 我该怎么做?只需要查看Storyboard中每个对象的名称,并确保它们与我的IBOutlet声明匹配即可。 - marked-down
1
选择您的每个控件、文本字段等,并在检查器窗口中检查它们的引用出口。 - Paulw11
1
您可以控制或右键单击您的Storyboard并打开源文件,然后使用cmd-f搜索theLoadMethod。某些内容正在引用该属性名称。 - Paulw11
如果我说错了,请纠正我,但是如果你的按钮名称是“Click This Button”,那么你将不得不将声明标记为“clickThisButton”或类似的内容。然后它应该可以工作。我有一个名为“Login”的按钮,当我尝试使用声明“loginButton”时,它失败了,但是当我将其更改为“login”时,它就可以工作了。相当古怪。我不确定如何解决这个问题。 - Brandon
显示剩余3条评论
5个回答

118

通常是由于故事板中链接到不存在的属性所致。请仔细检查故事板中对象的所有链接。如果更改了属性或方法的名称或拼写,它仍可能引用旧的内容。


9
在项目导航器中搜索出现问题的插座(在调试器中引用),它将被标记出来。通过单击插座旁边的 x 按钮来删除它(不要通过导航器选择并点击删除按钮)。 - cheznead
8
我遇到了同样的问题,并已经解决,也许这个链接可以帮助其他人解决问题。 - anztrax
这也可能发生在将场景/视图复制到故事板并重新链接到不同的视图控制器类之后。您需要查看视图上每个控件的插座,并在连接检查器中删除旧的插座。 - RowanPD
2
愿主保佑你的已出生和未出生的孩子。 - Mina
1
我在这里尝试了多次所有的方法。最终,我创建了一个新的视图和视图控制器来替换旧的,删除了有问题的那个,问题得到了解决。我也花了太多时间在这个问题上。 - dwaz

61

对于那些遇到相同问题,并已确保IBOutlets正常(至少在Interface Builder中看起来不错)的人: 请确保您的视图控制器的模块(参见附加的图像)设置为“Current-$(PROJECT_NAME)”。 输入图像描述


4
听到这个消息感到悲伤。但是究竟是什么不起作用呢?此外,答案本身从未被提出作为万能解决方法。 - Arthur Gevorkyan
2
@Rocotilos,如果您的项目有多个目标,则模块字段应与包含您的.xib/.storyboard文件的目标的名称相同。 - Arthur Gevorkyan
1
起初我认为这个答案不起作用 - 但是后来发现我必须“刷新”类(重新输入类名),这样才能将占位符文本添加到模块字段中。谢谢! - Jason
@omarojo,是的,这全部取决于文件的所有者。我假设,该模块保持为空(下拉列表也为空),是因为您还没有将“定义模块”(在您的目标->生成设置)标志设置为true。换句话说:确保您的项目中至少有一个模块 - Arthur Gevorkyan
1
+1,解决了我的问题。这已经让我烦了几个小时了。为什么新添加的视图控制器的默认设置是无,我永远也猜不到这是怎么发生的。 - Doug Watkins
显示剩余5条评论

23

我遇到了类似的问题。我修改了用户所需的字段并重命名了几个字段。

我在解析器中进行了所有必要的更改(删除和添加列)。后端不是问题所在。

您的界面构建器源代码仍包含旧属性。

要解决此问题,请右键单击Main.storyboard ->打开方式 ->源代码....查找您删除或重命名的字段...删除或修改它们...这取决于您所做的更改。

在您的情况下,您是否将LoadMethod从其他名称重新命名为该名称?

希望这能对某些人有所帮助。

干杯!


1
@Ronaldoh1非常感谢您的提示:“右键单击main.storyboard->打开为->源代码....查找您删除或重命名的字段...删除或修改它们。”这帮助我找到了从storyboard和编码器版本控制中删除但仍然让我头痛一个小时的可恶按钮,直到我读到您的提示。 - Dilshad Rana
2
谢谢。我的问题是将所有插座都分配给了文件的所有者,而不是直接分配给源。我所做的就是将文件以源代码方式打开并删除文件所有者的类名。再次感谢。 - davvilla
1
谢谢,这太棒了,对我很有用。 - KennethG
1
哇,那本来可能需要很长时间才能找到,太完美了! - TheZuck
1
你是一个传奇! - Nagra
显示剩余5条评论

3

只需右键单击并选择源代码选项卡来导航到您的Main.storyboard代码,然后删除存储的先前条目(应用程序会存储先前的条目,只需将其删除即可)。


谢谢!这才是真正起作用的!我来自程序员背景(C ++,Python,Java,...),虽然我喜欢所有漂亮的UI功能,比如从Storybody拖到代码中,但我感到不安,因为我不知道幕后发生了什么。 - JHolub

0
我也遇到了类似的错误。在更新 XCode 后,我通过将构建位置设置为自定义来解决该问题。只需将此字段设置为“相对于工作区”,就可以了。

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