6

有没有办法使用 NSCopying 而不返回的对象是 type Any?它总是强迫我投。这似乎很奇怪。我正在复制对象,Swift 不应该根据单词copy的定义知道它是同一类型吗?

是否有另一种方法可以复制我不知道的对象,或者是否有一些我缺少的“陷阱”需要这样做。

该类非常简单,例如:

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

它必须是一个类,因为我需要继承。

例子:

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

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

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

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

4

3 回答 3

6

这是NSObject 方法的Objective-C APIcopy

- (id)copy;

这转化为 Swift 为:

func copy() -> Any

因此,新对象没有附加类型信息;这就是为什么你必须投。

现在,如果您不喜欢这样,在您的情况下有一个简单的解决方案:不要采用 NSCopying 并且不要使用内置的 NSObjectcopy方法!编写你自己的一次性方法来克隆一个 Person ——例如一个名为 的实例方法makeClone()。NSObjectcopy很方便,但没有法律要求你使用它(除非有其他原因Person 需要遵守 NSCopying,例如它被用作 NSDictionary 的键,但我敢打赌你永远不会遇到任何此类理由)。

于 2017-04-28T15:32:37.180 回答
2

copy(with:)是 Objective C 方法的 Swift 导入版本,-copyWithZone. 在制定此协议时,Objective C 没有一种机制来表达copyWithZone应该返回与调用它相同的类型selfinstancetype被引入能够做到这一点,但NSCopying早于instancetype. 将其从 切换idinstancetype将是一个重大变化,因此从未完成。

于 2017-04-28T05:15:32.427 回答
1

根据我上面收到的信息和这篇返回 Self 的 Protocol func,这是一种不使用NSCopying.

因为自定义copy()返回的是对象的类型,而NSCopying's 的copy()返回Any,两者有不同的方法签名,所以可以使用自己的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()
于 2017-04-28T16:52:07.677 回答