2017-03-06 40 views
3

假設之間的週期我有以下代碼:保留class和struct

struct X { 
    let propertyOfTypeY: Y 
} 

class Y { 
    var propertyOfTypeX: X? 
} 

let y = Y() 
let x = X(propertyOfTypeY: y) 
y.propertyOfTypeX = x 

如果這些都是類的話,那將意味着保留週期。但是,我不清楚類和結構之間的區別是如何適用於上述示例的。它會導致一個保留週期,還是因爲struct的使用而成爲安全代碼?

回答

6

是的,你有一個保留週期。

y.propertyOfTypeX = x 

複製值xy.propertyOfTypeX,包括 屬性x.propertyOfTypeY這是y參考。

因此

y.propertyOfTypeX?.propertyOfTypeY === y 

成立。你有什麼本質上是一樣的

class Y { 
    var propertyOfTypeY: Y? 
} 

var y = Y() 
y.propertyOfTypeY = y 

只有propertyOfTypeYstruct X 的一部分(這x還有另外參考y)。

+0

注意'struct X {unowned let propertyOfTypeY:Y}'可能會允許循環被打破。 – Norman

3

TL; DR有一個保留週期,但您可以自己看到

struct X { 
    let propertyOfTypeY: Y 
} 

class Y { 
    var propertyOfTypeX: X? 

    deinit { 
     print("I was deinit'ed") 
    } 
} 

do { 
    let y = Y() 
    let x = X(propertyOfTypeY: y) 
    y.propertyOfTypeX = x 
} 
// y and x should be dealloc'ed here, because the "do scope" ends 

註釋掉y.propertyOfTypeX = xI was deinit'ed將被打印,但如果你這樣做分配,deinit不會被調用。

如果您使用閉包,則會發生同樣的情況。

+2

一個類似的「技巧」是將代碼放在一個'do {...}塊中,並檢查是否在執行塊之後調用deinit。即使使用非可選項也是如此。 –

+0

好點,讓它更容易理解。做出改變。 – Edgar