Подтвердить что ты не робот

Получите переменную Swift Variable Actual Name как String

Поэтому я пытаюсь получить имя фактической переменной как строку в Swift, но не нашел способ сделать это... или, возможно, я рассматриваю эту проблему и решение под плохим углом.

Так что это в основном то, что я хочу сделать:

var appId: String? = nil

//This is true, since appId is actually the name of the var appId
if( appId.getVarName = "appId"){
    appId = "CommandoFurball"
}

К сожалению, я не смог найти в яблочных документах все, что близко к этому, но это:

varobj.self or reflect(var).summary 

однако, это дает информацию о том, что внутри самой переменной или тип переменной в этом случае является String, и я хочу фактическое имя переменной.

4b9b3361

Ответ 1

В соответствии с обновленным с этим ответом он поддерживается в Swift 3 через #keyPath

NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Andrew")

Ответ 2

Это официально поддерживается в Swift 3 с помощью #keyPath()

https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md

Пример использования будет выглядеть так:

NSPredicate(format: "%K == %@", #keyPath(Person.firstName), "Wendy")

В Swift 4 у нас есть кое-что еще лучше: обозначение \KeyPath

https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md

NSPredicate(format: "%K == %@", \Person.mother.firstName, "Wendy")

// or

let keyPath = \Person.mother.firstName
NSPredicate(format: "%K == %@", keyPath, "Andrew")

Сокращение является долгожданным дополнением, и возможность ссылаться на ключевые пути из переменной является чрезвычайно мощной

Ответ 3

Это мое решение

class Test { 
    var name: String = "Ido"
    var lastName: String = "Cohen"
}

let t = Test()
let mirror = Mirror(reflecting: t)

for child in mirror.children {
    print(child.label ?? "")
}

печать будет

name
lastName

Ответ 4

Лучшее решение Здесь

Из данной ссылки

import Foundation

extension NSObject {
//
// Retrieves an array of property names found on the current object
// using Objective-C runtime functions for introspection:
// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
//
func propertyNames() -> Array<String> {
    var results: Array<String> = [];

    // retrieve the properties via the class_copyPropertyList function
    var count: UInt32 = 0;
    var myClass: AnyClass = self.classForCoder;
    var properties = class_copyPropertyList(myClass, &count);

    // iterate each objc_property_t struct
    for var i: UInt32 = 0; i < count; i++ {
        var property = properties[Int(i)];

        // retrieve the property name by calling property_getName function
        var cname = property_getName(property);

        // covert the c string into a Swift string
        var name = String.fromCString(cname);
        results.append(name!);
    }

    // release objc_property_t structs
    free(properties);

    return results;
}

}

Ответ 5

Я придумал быстрое решение, но, к сожалению, оно не работает с Ints, Floats и Doubles, я считаю.

func propertyNameFor(inout item : AnyObject) -> String{
    let listMemAdd = unsafeAddressOf(item)
    let propertyName =  Mirror(reflecting: self).children.filter { (child: (label: String?, value: Any)) -> Bool in
        if let value = child.value as? AnyObject {
            return listMemAdd == unsafeAddressOf(value)
        }
        return false
        }.flatMap {
            return $0.label!
    }.first ?? ""

    return propertyName
}

var mutableObject : AnyObject = object
let propertyName = MyClass().propertyNameFor(&mutableObject)

Он сравнивает адреса памяти для свойств объекта и определяет, совпадают ли они. Причина, по которой он не работает для Ints, Float и Doubles, потому что они не относятся к типу anyobject, хотя вы можете передать их как anyobject, когда вы это сделаете, они конвертируются в NSNumbers. поэтому адрес памяти меняется. они говорят об этом здесь.

Для моего приложения это совсем не мешало мне, потому что оно мне было нужно только для пользовательских классов. Так что, возможно, кто-то найдет это полезным. Если кто-то может сделать эту работу с другими типами данных, это было бы довольно круто.

Ответ 6

Это работает:

struct s {
    var x:Int = 1
    var y:Int = 2
    var z:Int = 3
}

var xyz = s()

let m = Mirror(reflecting: xyz)

print(m.description)
print(m.children.count)
for p in m.children {
    print(p.label as Any)
}