通过选择器 setProperty 设置 nsobject 子类的 属性

setting property of nsobject subclass by means of selector setProperty

我有 NSObject 的 subclass,我可以设置我的 subclass 的值:

performSelector(onMainThread:  Selector("setNameOfProperty:"), with: "myName", waitUntilDone: true)

其实我当然没有写任何名为setMethodProperty的方法。

所以这是我的简单 class:

class Post: NSObject {
    var name: String?
    var statusText: String?
    var profileImageName: String?
    var statusImageName: String?
    var numLikes: NSNumber?
    var numComments: NSNumber?

    var location: Location?

    override func setValue(_ value: Any?, forKey key: String) {
        if key == "location" {
            location = Location()
            location?.setValuesForKeys(value as! [String: AnyObject])
        } else {
            super.setValue(value, forKey: key)
        }
    }
}

A 然后从另一个 class 我只是调用方法 performSelector:

let samplePost = Post()
samplePost.performSelector(onMainThread:  Selector("setStatusText:"), with: "myName", waitUntilDone: true)

我正在寻找关于那个有趣的东西的任何信息,但我找不到。也许有人对此有 link 的了解,或者只是知道这种行为是什么。能不能写一下说明情况。

阅读 About Key-Value Coding 中有关 key-value 编码的更多信息,特别是:

Objects typically adopt key-value coding when they inherit from NSObject (directly or indirectly), which both adopts the NSKeyValueCoding protocol and provides a default implementation for the essential methods. Such an object enables other objects, through a compact messaging interface, to do the following:

Access object properties.

The protocol specifies methods, such as the generic getter valueForKey: and the generic setter setValue:forKey:, for accessing object properties by their name, or key, parameterized as a string. The default implementation of these and related methods use the key to locate and interact with the underlying data, as described in Accessing Object Properties.

通过子classing NSObject, Post class 实现 NSKeyValueCoding.

基本上是指在Post中定义的属性生成对应的getter和setter方法,也就是说可以使用performSelector来访问它们。这种 Key-Value 编码允许您执行选择器以获取或设置甚至您在编译期间不知道名称的属性 - 选择器可以从字符串变量创建。

如果您决定将项目迁移到 Swift 4,请注意,您必须使用 @objc 标记每个要以这种方式访问​​的 属性,或者在整个 class.

上使用 @objcMembers 注释