简体   繁体   English

如何在 Swfit 4.0 中使用键值编码?

[英]How do I use Key-Value Coding in Swfit 4.0?

I never used Swift4 before, and dont know how to use KVC in it.之前没用过Swift4,不知道里面怎么用KVC。
I try to create model with Dictionary, here the code:我尝试使用字典创建模型,代码如下:

class Person : NSObject {
    var name: String = ""
    var age: Int = 0

    init(dict: [String : Any]) {
        super.init()
        self.setValuesForKeys(dict)
    }
}

let dict: [String : Any] = ["name" : "Leon", "age" : 18]
let p = Person(dict: dict)
print(p.name, p.age)

There I get two question:我有两个问题:
1. Why dont I using AnyObject ? 1. 为什么我不使用AnyObject "Leon" and 18 was infer to String and Int , does it using in KVC? "Leon"18是推断StringInt ,它在 KVC 中使用吗?
2. @objc var name: String = "" , this form is worked, but I can not understand it. 2. @objc var name: String = "" ,这种形式是有效的,但我看不懂。

Thanks for all helps.感谢所有帮助。

To implement KVC support for a property in Swift 4, you need two things:要在 Swift 4 中为属性实现 KVC 支持,您需要做两件事:

  1. Since the current implementation of KVC is written in Objective-C, you need the @objc annotation on your property so that Objective-C can see it.由于当前 KVC 的实现是用 Objective-C 编写的,因此您需要在属性上添加@objc注释,以便 Objective-C 可以看到它。 This also means that the property's type needs to be compatible with Objective-C.这也意味着属性的类型需要与 Objective-C 兼容。

  2. In addition to exposing the property to Objective-C, you will need to set up your notifications in order for observers to be notified when the property changes.除了向 Objective-C 公开属性之外,您还需要设置通知,以便在属性更改时通知观察者。 There are three ways to do this:有三种方法可以做到这一点:

For stored properties, the easiest thing to do is to add the dynamic keyword like so:对于存储属性,最简单的方法是添加dynamic关键字,如下所示:

@objc dynamic var foo: String

This will allow Cocoa to use Objective-C magic to automagically generate the needed notifications for you, and is usually what you want.这将允许 Cocoa 使用 Objective-C 魔法为您自动生成所需的通知,并且通常是您想要的。 However, if you need finer control, you can also write the notification code manually:但是,如果需要更精细的控制,也可以手动编写通知代码:

@objc private static let automaticallyNotifiesObserversOfFoo = false
@objc var foo: String {
    willSet { self.willChangeValue(for: \.foo) }
    didSet { self.didChangeValue(for: \.foo) }
}

The automaticallyNotifiesObserversOf<property name> property is there to signify to the KVC/KVO system that we are handling the notifications ourselves and that Cocoa shouldn't try to generate them for us. automaticallyNotifiesObserversOf<property name>属性在那里向 KVC/KVO 系统表明我们自己处理通知并且 Cocoa 不应该尝试为我们生成它们。

Finally, if your property is not stored, but rather depends on some other property or properties, you need to implement a keyPathsForValuesAffecting<your property name here> method like so:最后,如果你的属性没有被存储,而是依赖于其他一些属性,你需要实现一个keyPathsForValuesAffecting<your property name here>方法,如下所示:

@objc dynamic var foo: Int
@objc dynamic var bar: Int

@objc private static let keyPathsForValuesAffectingBaz: Set<String> = [
    #keyPath(foo), #keyPath(bar)
]
@objc var baz: Int { return self.foo + self.bar }

In the example above, an observer of the baz property will be notified when the value for foo or the value for bar changes.在上面的示例中,当foo的值或bar的值发生变化时,将通知baz属性的观察者。

  1. In swift all class inherit NSObject are KVC compliant, there is type not instance, Any for type , AnyObject for instance 在swift中,所有类继承NSObject都符合KVC,类型不是实例,Any代表类型,AnyObject例如

  2. @objc is for objective-c class call it. @objc是针对objective-c类调用它的。

A key-path expression accepts property references and chained property references, such as \\Animal.name.count 键路径表达式接受属性引用和链接属性引用,例如\\ Animal.name.count

class Animal: NSObject {
    @objc var name: String

    init(name: String) {
        self.name = name
    }
}

let llama = Animal(name: "Llama")
let nameAccessor = \Animal.name
let nameCountAccessor = \Animal.name.count
llama[keyPath: nameAccessor]
// "Llama"
llama[keyPath: nameCountAccessor]
// "5"

Using Swift with Cocoa and Objective-C there are detail 使用Swift与Cocoa和Objective-C有详细说明

Everything was right for me but still I was getting this error, then I solved it by一切都适合我,但我仍然收到此错误,然后我解决了

  • Enabling the " Inherit module from Target " in the Identity Inspector.在身份检查器中启用“从目标继承模块”。 or要么
  • Giving the module(usually folder name/group name) in which it is present from the Identity Inspector under Custom Class从自定义类下的身份检查器中提供模块(通常是文件夹名称/组名称)
  1. your code你的代码

    var name: String = "" var age: Int = 0

    you can write the same code like this, when you are sure about its type.当您确定其类型时,您可以像这样编写相同的代码。

    var name = "" var age = 0

    Any is generally used for all types(function types and optional types), while AnyObject is used for Class types. Any 一般用于所有类型(函数类型和可选类型),而 AnyObject 用于 Class 类型。

  2. @objc have different meaning, when you use @objc in your swift class, that code is available in objective-c. @objc 有不同的含义,当您在 swift 类中使用 @objc 时,该代码在objective-c 中可用。 You should use @objc attribute to specify same as objective-c class, in result older archives can be replaced by new swift class.您应该使用@objc 属性指定与objective-c 类相同的属性,结果旧的存档可以被新的swift 类替换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM