2015-07-18 23 views
11

Benzer sorulara baktım ama memnun olduğum bir cevap görmedim.Swift geçiş yapısı referans ile mi?

Yapıları referans olarak vermek mümkün mü veya tavsiye edilebilir mi? Öyleyse nasıl? biryere çarparak Resmimi olmamasından dolayı bunu yapmanın benim ana nedenidir Gördüğünüz gibi

struct MyData { 
    var contentId: Int = 0 
    var authorId: Int = 0 
    var image: UIImage = UIImage(named: "myimage") 
} 

: Burada

örnekler için referans olarak bir koddur.

+1

Neyse ki resminiz bir referans türüdür ve UIImage'a referansta geçerek yaptığınız gibi, yapıyı değere göre kopyalamakla aynı maliyete katlanacaktır. –

+0

Bu bir kaynak ile iyi bir cevap olurdu – Esqarrouth

cevap

31

Yapılar inout anahtar sözcüğü ve & işleci kullanılarak başvuruya göre iletilebilir. Eğer bu size kritik bir durumda ihtiyaç performansı almak için tek yol olduğunu kanıtlamak sürece

struct Test { 
    var val1:Int 
    let val2:String 

    init(v1: Int, v2: String) { 
     val1 = v1 
     val2 = v2 
    } 
} 

var myTest = Test(v1: 42, v2: "fred") 

func change(test: inout Test) { 
    // you can mutate "var" members of the struct 
    test.val1 = 24 

    // or replace the struct entirely 
    test = Test(v1: 10, v2: "joe") 
} 
change(test: &myTest) 
myTest // shows val1=10, val2=joe in the playground 

Bu uygulama önerilmez.

Bunu yaparak UIImage kopyalamanın yükünü kaydetmeyeceğinizi unutmayın. Bir referans türünü bir yapının üyesi olarak koyduğunuzda, yalnızca referansı yalnızca değere aktardığınızda kopyalarsınız. Resmin içeriğini kopyalamıyorsunuz.

Yapı performansı hakkında bilmeniz gereken bir diğer önemli nokta ise kopyalama-yazma'dur. Array gibi birçok türde yerleşik değerler değer türleridir ve yine de çok performanslıdır. Swift'de bir yapının etrafından geçtiğinizde, siz onu değiştirene kadar kopyalama sorumluluğunu almazsınız.

Daha fazla bilgi için WWDC video on value types numaralı ürüne bakın.

3

Her şeyden önce, bir yapıyı geçirirseniz, normal olarak değere geçer. yapının tüm özelliklerini özelliklerine sadece işaretçi kopyalanan olsa UIImage gibi referans türleri (sadece 8 bayt) yinelenmiş olur hangi: yapılar içten referans olarak geçti ve kopyalanan böylece

var data1 = MyData() 
var data2 = data1 
// both data1 and data2 point to the same image 

Ayrıca derleyici kodu optimize gerekirse. Eğer inout parametreler kullanabilirsiniz üst düzey kodunda referans bir yapı geçirmeden bir örnek olarak

: Yani bir inout parametre başvuruyla geçirildi ancak inout uygulanması Swift'in genel yolu parametre değeri ile ve sonra geçişleri alır olduğunu edilebilir Bu işlev tekrar atanır.

Derleyici, işlev çağrısını en iyi duruma getirmesine rağmen, bazı durumlarda doğru bir başvuru alabilmeniz için. Bu optimizasyon, yalnızca hesaplanmamış veya willSet ve didSet (ve muhtemelen başka durumlar) gibi bir özellik gözlemcisine sahip değişkenleri etkiler.

Yani sadece fonksiyonun kapsamında değildir Mevcut örnek güvenmek gerekir: myTest görebilir ve t durumda 1'de sadece eşdeğer olduğundan

struct Test { 
    var value = 0 
} 

// case 1 
var myTest = Test() 

// case 2 
var myTest = Test() { 
didSet { print("I was set") } 
} 

// case 3 
var myTest: Test { 
get{ return Test() } 
set{ print("I set myself") } 
} 

func mutateTest(inout t: Test) { 
    // directly referencing to myTest 

    myTest.value // value = 0 in all cases 

    t.value = 42 
    myTest.value // value = 42 in case 1 ; value = 0 in case 2 and 3 

    t = Test() // nothing gets printed 
    myTest.value // value = 0 in all cases 

    t = Test() // nothing gets printed 
    t.value = 3 // value = 3 in case 1 ; value = 0 in case 2 and 3 
} 

changeTest(&myTest) 
//case 2: "I was set", case 3 "I set myself" get printed now 

myTest.value // value = 3 in all cases 

("true" referans semantik) . Bu, fonksiyonun kendisinde de myTest referansını verirseniz, bu büyük bir fark yaratır. Ama bunu yapmadığınız sürece, gitmekte fayda var.

İlgili konular