배열을 정확히 복제하려면 어떻게해야합니까?
Swift에서 배열 복제에 대한 정보를 찾는 데 어려움을 겪고 있습니다.
나는 사용해 보았다 .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
배열을 정확히 복제하려면 어떻게해야합니까?
Swift에서 배열 복제에 대한 정보를 찾는 데 어려움을 겪고 있습니다.
나는 사용해 보았다 .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
답변:
배열은 Swift에서 전체 값 의미 체계를 갖기 때문에 멋진 것이 필요하지 않습니다.
var duplicateArray = originalArray
당신이 필요한 전부입니다.
배열의 내용이 참조 유형이면 예, 객체에 대한 포인터 만 복사합니다. 내용의 전체 복사를 수행하려면 대신 map
각 인스턴스의 복사를 사용 하고 수행합니다. NSCopying
프로토콜 을 준수하는 Foundation 클래스의 경우 다음 copy()
메서드를 사용할 수 있습니다 .
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
여기에는 Swift의 값 의미 체계가 사용자를 보호하기 위해 작동하는 함정이 있습니다. 예를 들어, NSArray
변경 불가능한 배열을 나타 내기 때문에 해당 copy
메서드는 자신에 대한 참조를 반환하므로 위의 테스트는 예상치 못한 결과를 생성합니다.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
결과 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
다음과 같은 결과가 나타납니다. 복사중인 것처럼 보이지 않습니다 . 이유를 아십니까?
x[0] == x[1]
하지만 x[0] === y[0]
실패
Nate의 대답에 대한 세 번째 옵션이 있습니다.
let z = x.map { $0 } // different array with same objects
* 편집 됨 * 여기서 편집 시작
위는 본질적으로 아래와 동일하며 실제로 아래의 같음 연산자를 사용하면 배열이 변경되지 않는 한 복사되지 않기 때문에 성능이 더 좋습니다 (설계에 의한 것임).
let z = x
자세한 내용은 https://developer.apple.com/swift/blog/?id=10을 참조하십시오.
* 편집 됨 * 편집은 여기서 끝납니다.
이 배열에 추가하거나 제거해도 원래 배열에는 영향을주지 않습니다. 그러나 배열이 보유하고있는 객체의 속성을 변경하면 원래 배열에서 볼 수 있습니다. 배열의 객체는 복사본이 아니기 때문입니다 (배열이 원시 숫자가 아니라 객체를 보유한다고 가정).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
let z = x.map { $0.copy as! ClassX }
일반 객체의 경우 복사를 지원하는 프로토콜을 구현하고 객체 클래스가 다음과 같이이 프로토콜을 구현하도록하는 것이 가능합니다.
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
그리고 복제를위한 어레이 확장 :
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
그것은보기 코드를 꽤 많이하고 샘플이 확인 요점을
object's
init 함수
일부 클래스 객체의 배열 항목을 복사하려는 경우. 그런 다음 NSCopying 프로토콜을 사용하지 않고 아래 코드를 따를 수 있지만 개체에 필요한 모든 매개 변수를 가져와야하는 init 메서드가 있어야합니다. 다음은 놀이터에서 테스트 할 예제 코드입니다.
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray