【问题标题】:how to get single variable name from struct如何从结构中获取单个变量名
【发布时间】:2019-10-31 01:33:03
【问题描述】:

我有一个核心数据框架来处理你可以用coredata 做的所有事情,使其与可编码协议更加配合。我唯一剩下的就是更新数据。我通过将模型作为参数发送到它们的函数中来存储和获取数据。因此,如果我希望只更新我请求的模型中的 1 个特定值,我需要模型中的变量名称。

public func updateObject(entityKey: Entities, primKey: String, newInformation: [String: Any]) {
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityKey.rawValue)
        do {
            request.predicate = NSPredicate.init(format: "\(entityKey.getPrimaryKey())==%@", primKey)
            let fetchedResult = try delegate.context.fetch(request)
            print(fetchedResult)
            guard let results = fetchedResult as? [NSManagedObject],
                results.count > 0 else {
                    return
            }

            let key = newInformation.keys.first!
            results[0].setValue(newInformation[key],
                                forKey: key)
            try delegate.context.save()
        } catch let error {
            print(error.localizedDescription)
        }
    }

如您所见,newInformation 参数包含应更新的值的键和新值。但是,我不想通过("first": "newValue") 我想通过spots.first : "newValue"

如果我有这样的结构:

struct spots {
    let first: String
    let second: Int
}

我如何只得到 1 个名字?

我试过了:

extension Int {

    var name: String {
        return String.init(describing: self)
        let mirror = Mirror.init(reflecting: self)
        return mirror.children.first!.label!
    }
}

我希望能够说类似的话:

spots.first.name

但不知道怎么做

【问题讨论】:

  • 不理解问题陈述。请澄清。
  • get 1 name from this 是什么意思?
  • 你的愿望可能是错误的。 :) 任何时候你发现自己想要像这样自省,你就是在做一些不敏捷的事情。你应该向我们解释真正的问题是什么,这让你认为你需要这样做。
  • 通过使用镜像,我可以遍历孩子并打印 children.label 来获取名称,但我想要 1 个特定名称
  • 好的,接下来会有更深入的解释给我一秒钟

标签: swift mirror


【解决方案1】:

不确定我是否理解了问题,但是……这个呢?

class Spots: NSObject {
    @objc dynamic var first: String = ""
    @objc dynamic var second: Int = 0
}

let object = Spots()

let dictionary: [String: Any] = [
    #keyPath(Spots.first): "qwerty",
    #keyPath(Spots.second): 123,
]

dictionary.forEach { key, value in
    object.setValue(value, forKeyPath: key)
}

print(object.first)
print(object.second)

或者你可以试试 swift keypath:

struct Spots {
    var first: String = ""
    var second: Int = 0
}

var spots = Spots()

let second = \Spots.second
let first = \Spots.first

spots[keyPath: first] = "qwerty"
spots[keyPath: second] = 123

print(spots)

但是,如果您使用字典,将会有复杂(或不可能)的问题需要解决:

let dictionary: [AnyKeyPath: Any] = [
    first: "qwerty",
    second: 123
]

您需要将AnyKeyPath 转换回WritableKeyPath&lt;Root, Value&gt;,这看起来相当复杂(如果可能的话)。

for path in dictionary.keys {
    print(type(of: path).rootType)
    print(type(of: path).valueType)
    if let writableKeyPath = path as? WritableKeyPath<Root, Value>, let value = value as? Value { //no idea how to cast this for all cases
        spots[keyPath: writableKeyPath] = value
    }
}

【讨论】:

  • 这是一个很好的尝试,我自己也看过,但是我仍然绑定为keyPath,这限制了我,因为我需要它作为string。或者也许我只是没有像你解释的那样让它工作?
  • @Vollan 实际上 #keyPath(Spots.first) 会返回一个字符串“first”。但是您需要将其设为class 继承自NSObject 并将所有属性设置为@objc dynamic var
  • 是的,我知道这种方式,但我不想那样使用它:/对不起,谢谢
猜你喜欢
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2021-04-30
  • 1970-01-01
相关资源
最近更新 更多