NSCopying copy (with :) - do you really need to return Any?

Can NSCopying be used without a return type object Any

? It always makes me quit. It seems strange. I'm copying an object, shouldn't Swift know it's the same type by the definition of copy ?

Is there another way to copy objects that I am not aware of, or are there some "received" ones that I am missing for what it is required for.

The class is very simple, for example:

class Person {
   var name: String
   var age: Int
}

      

It must be a class because I need to have inheritance.

Example:

var john = Person(name: "John", age: 30)
var johnsClone = john.copy() as! Person

      

I guess I can create an initializer that takes an existing object, but that seems semantically less good than the word "copy".

init(person: Person) {
     return Person(name: person.name. age: person.age)
}

      

The only problem with implementing my own method clone()

is that I would also like to have a protocol that can call clone()

on many of these objects and implicitly return the same object type.

+3


source to share


3 answers


This is the Objective-C API for the NSObject method copy

:

- (id)copy;

      

This translates into Swift as:



func copy() -> Any

      

Thus, the type information is not tied to the new object; why should you quit.

Now, if you don't like that, there is an easy solution for your situation: don't use NSCopying and don't use the built-in NSObject method copy

! Write your own one-off method that clones a human - eg. an instance method called makeClone()

. NSObject copy

is a convenience, but no law requires you to use it (unless there is some other reason why Person should conform to NSCopying, for example it should be used as a key to an NSDictionary, but I'm sure you never face such a reason).

+4


source


copy(with:)

- is imported Swift version Objective C method -copyWithZone

. At the time this protocol was established, Objective C had no mechanism for expressing that it copyWithZone

should return the same type as the callee self

. instancetype

was introduced to be able to do just that, but NSCopying

predates existence instancetype

. Switching it from id

to instancetype

would be a change, so it was never done.



+2


source


Based on the information above and this post Function func returns Self , this is a way to do it without using NSCopying

.

As the user copy()

returns the object type and NSCopying

copy()

returns Any

, they have a different method signatures, so you can use your own copy()

without ambiguity.

protocol Copyable {
    init(copy: Self)
}

extension Copyable {
    func copy() -> Self {
        return Self.init(copy: self)
    }
 }

class Person: Copyable{

    var name: String
    var age: Int

   init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    required init(copy: Person) {
        self.name = copy.name
        self.age = copy.age
    }
 }


 let john = Person(name: "John", age: 30)
 let johnsClone = john.copy()

      

0


source







All Articles