Перебирать атрибуты класса объектов в Swift

Есть ли простой способ в Swift для итерации по атрибутам класса.

то есть. У меня есть класс Person, и у него есть 3 атрибута: имя, фамилия, возраст.

есть что-то вроде

for attribute in Person {
     println("\(attribute): \(attribute.value)")
}

вывод будет, например:

name: Bob
lastname: Max
age: 20

Ответ 1

Они удалили отражение в Swift 2.0. Вот как я перечисляю атрибуты и ценности.

class People {
    var name = ""
    var last_name = ""
    var age = 0
}

var user = People()
user.name  = "user name"
user.last_name = "user lastname"
user.age = 20

let mirrored_object = Mirror(reflecting: user)

// Swift 2
for (index, attr) in mirrored_object.children.enumerate() {
    if let property_name = attr.label as String! {
        print("Attr \(index): \(property_name) = \(attr.value)")
    }
}

// Swift 3
for (index, attr) in mirrored_object.children.enumerated() {
    if let property_name = attr.label as String! {
        print("Attr \(index): \(property_name) = \(attr.value)")
    }
}

Вывод:
Attr 0: name = имя пользователя
Attr 1: last_name = имя пользователя пользователя
Attr 2: age = 20

Ответ 2

Да, если вам просто нужно распечатать свойства структуры или класса, а свойства - простые типы, такие как String и Int, вы можете использовать reflect и MirrorType.

func print_properties(mirror: MirrorType) {
    for i in 0..<mirror.count {
        let (name, childMirror) = mirror[i]
        let value = childMirror.value
        println("\(i): \(name) = \(value)")
    }
}

struct Person {
    let first_name: String
    let last_name: String
    let age: Int
}

let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = reflect(john)
print_properties(mirror)

Если у вас есть вложенные структуры, перечисления, вам нужно сделать немного больше работы.

Ответ 3

Apple не удалила reflect, они просто изменили ее на _reflect, они также изменили MirrorType на _MirrorType.
Версия Swift 2.0 кода @Teemu Kurppa:

func print_properties(mirror: _MirrorType) {
  for i in 0..<mirror.count {
    let (name, childMirror) = mirror[i]
    let value = childMirror.value
    print("\(i): \(name) = \(value) ")
  }
}

struct Person {
    let first_name: String
    let last_name: String
    let age: Int
}

let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = _reflect(john)
print_properties(mirror)

Ответ 4

Как предположил @mohacs, Вы можете предоставить функцию Описание в вашем требуемом классе, например:

func description() -> String{

        let mirrored_object = Mirror(reflecting: self)
        let str:NSMutableString = NSMutableString()
        for (index, attr) in mirrored_object.children.enumerated() {
            if let property_name = attr.label as String! {
                str.append(" Attr \(index): \(property_name) = \(attr.value)")
            }
        }
        //print("desc=\(str)")
        return str as String
    }

Затем просто вызовите этот метод экземпляра

  let jsonOb:JsonModel = self.ObjArray[Index]
  print("jsonOb = \(jsonOb.description())")