NSCopying copy(with:) - 真的需要 return 吗?

NSCopying copy(with:) - Does it really need to return Any?

有没有什么方法可以在 returned 对象不是 Any 类型的情况下使用 NSCopying?它总是迫使我施法。这似乎很奇怪。我正在复制对象,难道 Swift 不应该根据 copy 这个词的定义知道它是同一类型吗?

是否有另一种方法来复制我不知道的对象,或者是否有一些我缺少的 "gotcha" 需要这个。

class很简单,比如:

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

必须是class因为我需要继承

示例:

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

我想我可以创建一个接受现有对象的初始化程序,但这在语义上似乎不如 "copy" 这个词好。

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

我在实现自己的 clone() 方法时遇到的唯一问题是我还希望有一个协议可以调用 clone() 许多此类对象并隐式调用 return相同的对象类型。

copy(with:) 是 Swift 导入版本的 Objective C 方法,-copyWithZone。在制定此协议时 Objective C 没有一种机制来表达 copyWithZone 应该 return 与它所调用的 self 相同的类型。 instancetype 的引入就是为了能够做到这一点,但是 NSCopying 早于 instancetype 的存在。将它从 id 切换到 instancetype 将是一个重大更改,因此从未完成。

这是 NSObject 方法的 Objective-C API copy:

- (id)copy;

转换为 Swift 为:

func copy() -> Any

因此,没有类型信息附加到新对象;这就是你必须施法的原因。

现在,如果您不喜欢那样,在您的情况下有一个简单的解决方案:不要采用 NSCopying 并且不要使用内置的 NSObject copy 方法!编写您的 own 克隆一个 Person 的一次性方法——例如一个名为 makeClone() 的实例方法。 NSObject copy 很方便,但没有法律要求你使用它(除非有 some other reason 为什么 Person 需要符合 NSCopying,例如它被用作 NSDictionary 的键,但我我打赌你永远不会遇到任何这样的原因)。

根据我上面收到的信息和这个 post Protocol func returning Self,这是一种不使用 NSCopying 的方法。

因为自定义copy()returns对象的类型,而NSCopyingcopy()returnsAny,这两个有不同的方法签名,所以你可以使用你自己的 copy() 而不会产生歧义。

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()