Question: I have created multiple classes, all of which need to implement the NSCopying protocol, but there are a lot of properties in my classes, is there an easier way?
Below is my current way：

```
    class TestA: NSObject, NSCopying {
    var a: CGFloat = 0
    var b: CGFloat = 0

    required override init() {

    }

    func copy(with zone: NSZone? = nil) -> Any {
        let item = type(of: self).init()
        item.a = a
        item.b = b
        return item
    }
}

class TestB: TestA {
    var c: CGFloat = 0
    var d: CGFloat = 0

    override func copy(with zone: NSZone? = nil) -> Any {
        let item = super.copy(with: zone) as! TestB
        item.c = c
        item.b = b
        return item
    }
}

```

My thought is, can we take all the properties of the class, automatically create a new object, assign values to the new object?

Answer: 
You can look at [KeyValueCoding](https://github.com/ikhvorost/KeyValueCoding) package with `KeyValueCoding` protocol which implements enumeration of all properties of an object and setting values by key paths for pure swift classes and structs.

Based on it you can implement `Copying` protocol:

```swift
protocol Copying: KeyValueCoding {
    init()
}

extension Copying {
    func makeCopy() -> Self {
        var item = Self()
        var _self = self
        metadata.properties.forEach {
            item[$0.name] = _self[$0.name]
        }
        return item
    }
}

```

How it works:

```swift
class TestA: Copying {
    var a: CGFloat = 1
    var b: Int = 2

    required init() {}
}

class TestB: TestA {
    let c: String = "Hello Copy!"
    let d: Date = Date(timeIntervalSince1970: 123456789)
}

let objectA = TestA()
objectA.a = 100
objectA.b = 200
let copiedA = objectA.makeCopy()
print(copiedA.a) // "100.0"
print(copiedA.b) // "200"

let objectB = TestB()
objectB.a = 100
objectB.b = 200
let copiedB = objectB.makeCopy()
print(copiedB.a) // "100.0"
print(copiedB.b) // "200"
print(copiedB.c) // "Hello Copy!"
print(copiedB.d.timeIntervalSince1970) // "123456789.0"

```

So as you can see this approach works with inherited properties as well.

Moreover it works with structs:

```swift
struct MyStruct: Copying {
    let a = 1.0
    let b = 2
    let c = "c"
}

let myStruct = MyStruct()
let copied = myStruct.makeCopy()
print(copied) // MyStruct(a: 1.0, b: 2, c: "c")

```
I think I've found a solution, but I'm not sure if this will have any ill effects. Can someone tell me what's wrong with this。Thanks！

```
  @objcMembers class TestA: NSObject, NSCopying {
    var a: CGFloat = 0
    var b: CGFloat = 0
    var c: CGFloat = 0

    required override init() {

    }

    func copy(with zone: NSZone? = nil) -> Any {
        let item = type(of: self).init()
        for property in getAllPropertys() {
            let value = self.value(forKey: property)
            item.setValue(value, forKey: property)
        }
        return item
    }

    func getAllPropertys()->[String]{
        var result = [String]()
        var count:UInt32 = 0
        let proList = class_copyPropertyList(object_getClass(self),&count)
        for i in 0..<numericCast(count) {
            let property = property_getName((proList?[i])!);
            let proper = String.init(cString: property)
            result.append(proper)
          }
          return result
    }
}

```