使用KVC的Swift可选属性导致崩溃 [英] Swift optional property using KVC causes crash

查看:211
本文介绍了使用KVC的Swift可选属性导致崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在Swift中使用KVC会引起很多问题,尤其是在使用可选属性时.

这是我的具体问题:

这是一个名为的班级.它具有一个称为 age 的常规属性,以及一个名为 ageOptional 的Optional(Int)属性.

class Person: NSObject {

    var age: Int

    var ageOptional: Int?


    override init(age: Int){

        self.age = 0
    }
}

现在,我在Person的实例中使用KVC:

//new a instance
var person = Person()

//kvc for normal property: it work well
person.setValue(28, forKeyPath: "age")


//but, this time ,it doesn't work well!!!!
person.setValue(28, forKeyPath: "ageOptional")

该应用程序崩溃了,这是一个例外:

2015-07-11 11:17:31.546 CFRuntime [4646:607] ***由于未捕获的异常'NSUnknownKeyException'而终止应用程序,原因:'[setValue:forUndefinedKey:]: 此类不适用于密钥ageOptional的键值编码.'

我发现,如果属性是可选的,则KVC找不到密钥.但是,我找不到用于可选属性的有用键,并且无法解决这种情况.

解决方案

您已经完美地解决了该问题.您不能在Optional Int属性上使用KVC,因为KVC是Cocoa/Objective-C,而Objective-C无法看到Optional Int-它没有桥接到Objective-C. Objective-C只能看到桥接到Objective-C的类型:

    源自NSObject的
  • 类类型

  • @objc

    公开的
  • 类类型

  • 已桥接的Swift结构

Objective-C几乎也可以看到包装了这些类型的Optional.它可以看到Optional包装桥接的结构,但前提是该结构是直接桥接的. Int是直接桥接的;它被桥接到NSNumber,但不是直接桥接(必须包装).因此,Objective-C无法看到键入为Int?的Swift成员.

如果您确实需要此选项为Optional,并且确实需要在其上使用KVC,则将其声明为NSNumber?,而不是Int?.就我个人而言,我会怀疑其中哪一项是正确的.自从将我所有的应用程序从Objective-C转换为Swift以来,我发现我实际上并不需要内部的KVC,而且我所有基于KVC的解决方案都可以通过其他更好的方法来完成.

I found that using KVC in Swift causes many problems, especially with optional properties.

Here is my specific problem:

Here is a Class named Person. It has a normal property called age,and a Optional(Int) property called ageOptional.

class Person: NSObject {

    var age: Int

    var ageOptional: Int?


    override init(age: Int){

        self.age = 0
    }
}

Now, I use KVC in Person's instance:

//new a instance
var person = Person()

//kvc for normal property: it work well
person.setValue(28, forKeyPath: "age")


//but, this time ,it doesn't work well!!!!
person.setValue(28, forKeyPath: "ageOptional")

The app crashes, and here is the exception:

2015-07-11 11:17:31.546 CFRuntime[4646:607] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key ageOptional.'

I found that, if a property is optional, KVC couldn't find the key. But,I can't find the useful key for an optional property ,and resolve this situation.

解决方案

You have already solved the problem perfectly. You cannot use KVC on an Optional Int property, because KVC is Cocoa / Objective-C, and Objective-C cannot see an Optional Int - it is not bridged to Objective-C. Objective-C can only see types that are bridged to Objective-C:

  • class types that are derived from NSObject

  • class types that are exposed with @objc

  • Swift structs that are bridged

Objective-C can also see an Optional wrapping any of those types - almost. It can see an Optional wrapping a bridged struct, but only if that struct is directly bridged. Int is not directly bridged; it is bridged to NSNumber, but not directly (it has to be wrapped). Thus, Objective-C cannot see a Swift member typed as an Int?.

If you really need this to be an Optional, and if you really need to use KVC on it, then declare it as NSNumber?, not Int?. Personally, I would doubt whether either of those things is true; since converting all my apps from Objective-C to Swift, I've found that I don't actually need KVC internally, and that all my KVC-based solutions can be done some other, better way.

这篇关于使用KVC的Swift可选属性导致崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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