2017-03-06 63 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