Swift:返回对象的副本

Swift:返回对象的副本,swift,nsarray,Swift,Nsarray,我需要使用Swift返回一个对象的副本,但我不知道如何执行此操作 我将在Objective-C中这样做: -(NSArray*) doingSomethingwith { NSArray *myArray = @[@"a",@"b",@"c",@"d",]; return [myArray copy]; } 你们有人知道怎么做吗 我非常感谢你的帮助。斯威夫特不接受推荐人。因此,您可以直接返回数组。您可以这样做 let myArray: NSArray = ["a","b","

我需要使用Swift返回一个对象的副本,但我不知道如何执行此操作

我将在Objective-C中这样做:

-(NSArray*) doingSomethingwith
{
    NSArray *myArray = @[@"a",@"b",@"c",@"d",];

    return [myArray copy];
}
你们有人知道怎么做吗


我非常感谢你的帮助。

斯威夫特不接受推荐人。因此,您可以直接返回数组。

您可以这样做

let myArray: NSArray = ["a","b","c","d"]

func returnCopyOfArray() -> NSArray{
return myArray
}

如果数组的内容是值对象(如示例中的常量字符串),则只需返回它;Swift作业具有复制行为。这在Apple文档的末尾进行了解释:

字符串、数组和字典的赋值和复制行为

在Swift中,许多基本数据类型(如字符串、数组和字典)都实现为结构。这意味着字符串、数组和字典等数据在分配给新常量或变量时,或在传递给函数或方法时,都会被复制

此行为与Foundation不同:NSString、NSArray和NSDictionary是作为类而不是结构实现的。在基础中,字符串、数组和字典总是被指派并传递给现有实例,而不是作为副本。

注意:上面的描述是指字符串、数组和字典的“复制”。您在代码中看到的行为将始终像复制发生一样。但是,Swift仅在绝对必要的情况下在幕后执行实际复制。Swift管理所有值复制以确保最佳性能,您不应避免分配以尝试抢占此优化


如果您的数组包含引用对象,并且您希望返回它们的深度副本,那么这就有点麻烦了;关于如何处理这个问题。尽管正确的处理方法是重做代码以使用值类型。

好的,您可以使对象符合NSCopying

class Person: NSObject, NSCopying {
var firstName: String
var lastName: String
var age: Int

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

func copy(with zone: NSZone? = nil) -> Any {
    let copy = Person(firstName: firstName, lastName: lastName, age: age)
    return copy
 }
}
然后你可以打电话给复印部

让clone=myPerson.copy()

如果没有实现该类,那么如果该类具有
public
open
访问权限,则可以潜在地扩展该类

extension Person: NSCopying {
  func copy(with zone: NSZone? = nil) -> Any {
    let copy = Person(firstName: firstName, lastName: lastName, age: age)
    return copy
 }
}

您想知道如何返回NSArray副本还是如何返回任意对象副本?这不是真的。如果有引用类型的Swift数组,直接返回该数组不会创建深度副本。两个副本仍将引用同一个对象,更改其中一个也会更改另一个。@WillM。有些道理。但是,让我们有一个swift数组和NSMUTABLEARRY,如果我们将其传递给另一个控制器(例如,执行segue)并尝试编辑它们,swift数组将不会在上一个控制器中更改,但会在上一个控制器的NSMUTABLEARRY中更改。在这里查看答案。他引用的例子是,如果他直接返回数组,这不会产生任何问题,因为每次创建一个新数组时,这只会“起作用”,因为它们是不可变的。所有副本仍然指向相同的对象,而不是真正的副本。您可以通过打印myArray[0]的内存地址和副本的第一个元素来判断。