如何测试“NSObject”是否具有可以设置的任意名称的属性



我想从字典中实现模型的泛型填充。我使用以下测试测试模型是否具有属性,但条件总是失败:

if (self.responds(to:(NSSelectorFromString(keyName)))){
    self.setValue(keyValue, forKey: key )
}

下面是一个示例代码:

import UIKit
class myModel: NSObject {    
    var userName: String = ""
    var phoneNumber: String = ""
    init(dict: Dictionary<String, Any>) {
        super.init()
        for (key, value) in dict {
            let keyName = key     
            let keyValue: String = String(describing: value)
            print("key (key) value (value)")
            if (self.responds(to:(NSSelectorFromString(keyName)))){
                self.setValue(keyValue, forKey: key )
            }
        }          
    }        
}

你快完成了。在 NSObject 类的顶部添加以下内容 - @objcMembers

如-

import UIKit
@objcMembers
class myModel: NSObject { 

这如您所料(在操场上测试(:

import UIKit
class myModel: NSObject {
    @objc var userName: String = ""
    @objc var phoneNumber: String = ""
    init(dict: Dictionary<String, Any>) {
        super.init()
        for (key, value) in dict {
            let keyCapitalized = key.prefix(1).uppercased() + key.dropFirst()
            let keyName = "set(keyCapitalized):"
            let keyValue: String = String(describing: value)
            print("key (key) (selector: '(keyName))' value (value)")
            if self.responds(to: Selector(keyName)) {
                self.setValue(keyValue, forKey: key)
            }
        }
    }
}
let m = myModel(dict: ["userName" : "milan", "data" : "data"])
print(">>> (m.userName)") // prints ">>> milan"
print(">>> (m.phoneNumber)") // prints ">>> " (number was not provided, and data key was ignored)

只有两点。

首先,您需要将这些属性公开给 ObjectiveC 才能responds()工作 - 因此我在这两个属性上都添加了@objc注释。

其次,测试是否可以设置名为 userName 的属性的正确选择器语法不是 Selector("userName") ,而是Selector("setUserName:")(您正在测试一个 setter(。

字典

需要为其键和值指定一个类型。初始化器中的内容太模糊了。

因为从字典中获取某些内容的结果可能是 nil,所以您需要提供一个默认值,即??之后发生的情况

class MyModel: NSObject {
    var userName: String = ""
    var phoneNumber: String = ""
    init(dict: [String : String]) {
        self.userName = dict["userName"] ?? ""
        self.phoneNumber = dict["phoneNumber"] ?? ""
        super.init()
    }
}

您可以通过以下方式从字典中设置模型值。

class MyModel {
    var userName: String?
    var phoneNumber: String?
    init(dict: [String:Any]?) {
        self.userName = dict?["username"] as? String
        self.phoneNumber = dict?["phonenumber"] as? String
    }
}

示例用法 :

let myModel = MyModel(dict: ["username":"test","phonenumber":"1234567890"])

最新更新