Bir dizinin tam olarak kopyasını nasıl yapabilirim?
Swift'de bir dizinin kopyalanması hakkında bilgi bulmakta zorlanıyorum.
Kullanmayı denedim .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Bir dizinin tam olarak kopyasını nasıl yapabilirim?
Swift'de bir dizinin kopyalanması hakkında bilgi bulmakta zorlanıyorum.
Kullanmayı denedim .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Yanıtlar:
Diziler, Swift'de tam değerli semantiğe sahiptir, bu nedenle süslü hiçbir şeye gerek yoktur.
var duplicateArray = originalArray
tüm ihtiyacın olan.
Dizinizin içeriği bir başvuru türü ise, evet, bu yalnızca işaretçileri nesnelerinize kopyalar. İçeriğin derin bir kopyasını gerçekleştirmek için, bunun yerine map
her bir örneği kullanır ve bir kopyasını gerçekleştirirsiniz. NSCopying
Protokole uyan Temel sınıfları için şu copy()
yöntemi kullanabilirsiniz :
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Burada Swift'in değer semantiğinin sizi korumaya çalıştığı tuzaklar olduğuna dikkat edin - örneğin, NSArray
değişmez bir diziyi temsil ettiğinden , copy
yöntemi yalnızca kendisine bir referans döndürür, böylece yukarıdaki test beklenmedik sonuçlar verir.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
ve şu çıktıyı aldım: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
Kopyalanmış gibi görünmüyor, nedenini biliyor musunuz?
x[0] == x[1]
ama x[0] === y[0]
başarısız olmalı
Nate haklı. İlkel dizilerle çalışıyorsanız tek yapmanız gereken duplicateArray öğesini originalArray öğesine atamaktır.
Eksiksizlik adına, bir NSArray nesnesi üzerinde çalışıyor olsaydınız, NSArray'in tam bir kopyasını yapmak için aşağıdakileri yaparsınız:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
Nate'in cevabı için üçüncü bir seçenek var:
let z = x.map { $0 } // different array with same objects
* DÜZENLENMİŞ * düzenleme burada başlar
Yukarıdakiler esasen aşağıdaki ile aynıdır ve aşağıdaki eşitlik operatörünü kullanmak daha iyi sonuç verecektir çünkü dizi değiştirilmedikçe kopyalanmayacaktır (bu tasarım gereğidir).
let z = x
Daha fazlasını buradan okuyun: https://developer.apple.com/swift/blog/?id=10
* DÜZENLENMİŞ * düzenleme burada biter
bu diziye eklemek veya çıkarmak orijinal diziyi etkilemez. Bununla birlikte, nesnelerin herhangi birinin dizinin tuttuğu özelliklerin değiştirilmesi orijinal dizide görülür. Çünkü dizideki nesneler kopya değildir (dizinin ilkel sayıları değil, nesneleri tuttuğunu varsayarak).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, bir diziyi çoğaltın:let z = x.map { $0.copy as! ClassX }
Normal nesneler için yapılabilecek, kopyalamayı destekleyen bir protokol uygulamak ve nesne sınıfının bu protokolü şu şekilde uygulamasını sağlamaktır:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
Ve sonra klonlama için Array uzantısı:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
ve bu hemen hemen, kodu görüntülemek ve bir örneği kontrol etmek için bu özü
object's
init fonksiyonu
Bir sınıf nesnesinin bir dizisinin öğelerini kopyalamak istiyorsanız. Daha sonra NSCopying protokolünü kullanmadan aşağıdaki kodu takip edebilirsiniz, ancak nesneniz için gerekli olan tüm parametreleri alması gereken bir init yöntemine sahip olmanız gerekir. İşte oyun alanında test etmek için bir örnek için kod.
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