美文网首页
swift备忘录之arc

swift备忘录之arc

作者: byn | 来源:发表于2017-02-10 12:05 被阅读16次

swift中的arc与oc中很相似。需要注意的是swift中arc处理循环引用的关键字及其使用方式与oc中有所区分。循环引用在oc中,主要使用关键字weak或者unsafe_unretained来处理。在swift中使用weak和unowned来处理。

weak和unowned都表示不持有对象,区别在于,weak修饰的是optional的值,unowned修饰的是一定存在的值。也就是说weak修饰的var在运行时可以为nil,而unowned修饰的不可以。如果一个值使用unowned修饰,由于unowned修饰的值会自动解包,所以使用的时候,就不用加!符号了。

class instance中的使用例子

class Country {
    let name: String
    var capitalCity: City!
    init(name: String, capitalName: String) {
        self.name = name
        self.capitalCity = City(name: capitalName, country: self)
    }
}
 
class City {
    let name: String
    unowned let country: Country
    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

摘录来自: Apple Inc. “The Swift Programming Language (Swift 3)”。 iBooks. 

Country和City类互相持有对方,如果不加unowned关键字,就会形成循环引用。如果City规定country属性不是必须有,则修饰的关键字可以改成weak,但是同时let也必须改成var,因为在运行时country可能有值,也可能为nil。

closure中的使用例子

如果closure赋值给一个var,然后在closure中又使用了类中的property等,那么会造成循环引用。例如:

class HTMLElement {
    
    let name: String
    let text: String?
    
    lazy var asHTML: () -> String = {
        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 {
        print("\(name) is being deinitialized")
    }
    
}

//使用
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
// Prints "<p>hello, world</p>

摘录来自: Apple Inc. “The Swift Programming Language (Swift 3)”。 iBooks. 

其内存引用关系为:

closureRecycle.png

破除这么循环引用的方式是添加capture list。如下所示:

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

摘录来自: Apple Inc. “The Swift Programming Language (Swift 3)”。 iBooks. 

这个capture list放在closure的参数和返回值之前。

如果closure没有参数和返回值,那么需要这样写:

lazy var someClosure: () -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // closure body goes here
}

摘录来自: Apple Inc. “The Swift Programming Language (Swift 3)”。 iBooks. 

通过in关键字将capture list和其他部分隔离开。上面这个例子中,改成如下方式就可以解除循环引用:

class HTMLElement {
    
    let name: String
    let text: String?
    
    lazy var asHTML: () -> String = {
        [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 {
        print("\(name) is being deinitialized")
    }
    
}

摘录来自: Apple Inc. “The Swift Programming Language (Swift 3)”。 iBooks. 

参考

《The Swift Programming Language》

相关文章

  • swift备忘录之arc

    swift中的arc与oc中很相似。需要注意的是swift中arc处理循环引用的关键字及其使用方式与oc中有所区分...

  • swift内存管理

    ARC 跟OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间) Swift的ARC中有3种引...

  • Automatic Reference Counting (自动

    Swift usesAutomatic Reference Counting(ARC) to track and ...

  • 16_自动引用计数

    在 Swift 使用 ARC 与在 Obejctive-C 中使用 ARC 类似,具体请参考过渡到 ARC 的发布...

  • Swift:基础(二十七)自动引用计数

    Swift 自动引用计数(ARC) Swift 使用自动引用计数(ARC)这一机制来跟踪和管理应用程序的内存 通常...

  • Swift-内存管理,指针

    内存管理 Swift采用引用计数的ARC内存管理方案(堆空间) Swift的ARC中有3钟引用强引用弱引用(wea...

  • Swift:weak与unowned的奥秘

    Swift uses Automatic Reference Counting (ARC) to track an...

  • Swift : 内存泄露原因及解决办法

    Swift 自动引用计数(ARC) 在Swift中 使用自动引用计数(ARC)这一机制来跟踪和管理应用程序的内存 ...

  • 内存管理

    内存管理 跟OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间) Swift的ARC中有3种...

  • 十七、内存管理

    内存管理 跟OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间) Swift的ARC中有3中...

网友评论

      本文标题:swift备忘录之arc

      本文链接:https://www.haomeiwen.com/subject/uqjgittx.html