/* ARC 感觉跟python太像了有木有。Automatic Reference Counting
✨✨Unowned reference其实也是一种weak引用,它的意思是当它处于不被拥有时,它就变为无效。
从另一方面讲unowned定义的引用,通常被认为必须要有效的,一旦指向的对象被释放,就变得没有意义。
class Person { var card: CreditCard? } class CreditCard { unowned let holder: Person init (holder: Person) { self.holder = holder } }
weak指向的对象被释放变为nil,unowned指向的对象被释放后不会变为nil,被调用时会出现异常。
所以这两个使用的对象就不一样了,当是可有可无的关系,
比如房屋和租户可以相互不拥有,则房屋类中 weak 租户=租户
但是信用卡和拥有者 ,信用卡的类中不可以缺少拥有者 unowned拥有者= 拥有者
1.强引用
2.强引用死锁
3.弱引用(weak reference),弱引用代表其随时都会被赋值为nil,
所以不能是const,并且需要是optional的。
4.无主引用(Unowned reference)
在被赋值之后很可能会变成nil的变量,尽量使用弱引用,相反在被赋值后不会变成nil的变量尽量用无主引用。
比如 dat = var,如果执行这句之后,var很可能变成nil则弱引用,若永远不会变成nil则无主引用。
如果变量var被deinit后,dat会自动变为nil
与弱引用总是定义为optional相反,无主引用总是定义为非optional的。
✨✨ 在beta5中如果想前向引用,则与所引用的类型中间不能有实例定义,但是允许类型定义,参见下面Person例子 */
class Person
{
let name:String
//✨✨在beta3中如果想引用未定义的类型则其类型定义必须紧随该变量,中间不能有实例定义
//但是允许类型定义
var apartment:Apartment?
init(name:String)
{
self.name = name
println("\(name) is initialized!")
}
deinit//注意deinit没有小括号
{
println("\(name) is deinit")
}
}
// var testFowardRefenerce:Person? 如果有这个定义,Person中就不认识Apartment
class TMP //类型定义是可以的。
{
}
/* 2.强引用死锁 */
class Apartment
{
var person:Person?
}
var ref1:Person?
var ref2:Person?
ref1 = Person(name:"A")
println("1")
ref2 = ref1//现在ref1和ref2都对Person对象进行了Strong reference
println("2")
ref1 = nil//删除ref1还有ref2的强引用,所以不会调用析构函数
println("3")
ref2 = nil//这个变量也被删除,则没人再引用Person,这时会调用析构函数。
println("4")
var a:Apartment? =Apartment()
var p:Person? =Person(name:"Person")
p!.apartment = a
a!.person = p
p = nil//由于p在a中被强引用,所以不能deinit
a = nil//由于p没有被deinit,p还存在,而a被p引用造成死锁。
/* 3.弱引用语法在前面加weak关键字 */
class WeakApartment
{
weak var person:Person?
}
/* 4.无主引用
无主引用理解起来感觉比较困难,我的理解是必须有主才行,如果类实例的无主类型只想的类型被nil后
那么类实例本身会被deinit
*/
class Unowned
{
unowned var p:Person //无主引用被定义为非optional的。
var test:Int = 3
init(p:Person)
{
self.p = p
println("Unowned is init")
}
deinit
{
println("Unowned is deinit")
}
}
var person:Person? =Person(name:"Person")
var unowned:Unowned? =Unowned(p:person!)
person = nil
//unowned = nil
println(unowned!.p)//与weak的nil不同,没有主人后,是不可以访问的。
/* 类中引用闭包,闭包中capture类中的成员造成的引用锁解决办法
[unowned self]
*/
class HTMLElement {
let name:String
let text:String?
@lazyvar asHTML: () ->String = {
//如果不加上unowned self则asHTML被赋值给外部后,产生了外部强引用
//闭包内部引用name等,不能析构,而闭包内部又无法被删除导致死锁。
[unowned self] in
if let text = self.text
{
return"<\(self.name)>\(text)</\(self.name)>"
}
else
{
return"<\(self.name) />"
}
}
init(name:String, text:String? =nil)
{
self.name = name
self.text = text
}
deinit {
println("\(name) is being deinitialized")
}
}