-3

I'm need to return a copy of an object using Swift but I can not figure out how to do this.

This how I'll do it in Objective-C:

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

    return [myArray copy];
}

Any of you knows how to do this Swift?

I'll really appreciate your help.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
user2924482
  • 8,380
  • 23
  • 89
  • 173

4 Answers4

3

If the contents of the array are value objects, as the constant strings are in your example, then simply return it; Swift assignments have copy behaviour. This is explained at the end of the Classes And Structures Apple documentation:

Assignment and Copy Behavior for Strings, Arrays, and Dictionaries

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

This behavior is different from Foundation: NSString, NSArray, and NSDictionary are implemented as classes, not structures. Strings, arrays, and dictionaries in Foundation are always assigned and passed around as a reference to an existing instance, rather than as a copy.

NOTE: The description above refers to the “copying” of strings, arrays, and dictionaries. The behavior you see in your code will always be as if a copy took place. However, Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization.

If your array contains reference objects, and you want to return a deep copy of them, that's a little trickier; here's a discussion about how to handle that. Although the correct way to handle that would be to redo your code to use value types.

Community
  • 1
  • 1
Alex Curylo
  • 4,744
  • 1
  • 27
  • 37
1

You could do something like this.

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

func returnCopyOfArray() -> NSArray{
return myArray
}
JoakimE
  • 1,820
  • 1
  • 21
  • 30
  • This only "works" because they aren't mutable. All copies are still pointing at the same objects, instead of being true copies. You can tell by printing the memory address of myArray[0] and the first element of your copy. – Will M. May 19 '16 at 18:54
0

Well, you could make the object conform to 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
 }
}

Then you can call copy on it.

let clone = myPerson.copy()

If you didn't implement the class, then you can potentially extend the class if it has public or open access.

extension Person: NSCopying {
  func copy(with zone: NSZone? = nil) -> Any {
    let copy = Person(firstName: firstName, lastName: lastName, age: age)
    return copy
 }
}
ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
-1

Swift doesn't take references. So, you can directly return the array.

Bhavuk Jain
  • 2,167
  • 1
  • 15
  • 23
  • 1
    This is not true. If you have a Swift array of reference types, directly returning the array does not create a deep copy. Both copies will still reference the same object, and changing one also changes the other. – Will M. May 19 '16 at 18:45
  • @WillM. Somewhat true. But lets have a swift array and nsmutablearray and if we pass it to another controller(eg. perform segue) and try editing them, the swift array will not change in previous controller but it will get changed in nsmutablearray in previous controller. Check out the answer here. http://stackoverflow.com/questions/36208709/creating-a-mutable-dictionary-in-swift – Bhavuk Jain May 20 '16 at 10:46
  • And the example that he has referenced, if he directly return the array, it won't make any problem because everytime a new array is created. – Bhavuk Jain May 20 '16 at 10:47