2015-01-04 31 views
0

編譯程序時出現運行時錯誤,故意SomeObject的實例化是短暫的,但獲得的塊通過捕獲引用,在操場中不起作用,但在編譯程序時顯示錯誤並運行。暫時在塊中捕獲自己

目標是臨時保存短期對象SomeObject的引用,直到回調完成。

編輯 - 如果我評論[unowned self]go它的作品,因爲我相信它創建了一個有力的參考,但希望沒有內存泄漏有??? (無論如何,調用者對象都超出了範圍)。請確認我不應該在這裏使用[unowned self]

import Foundation 

class SomeObject { 

    func go() { //i guess problem is here, it can't find self, 
     anotherObject.asyncCall({ [unowned self] in //works if i comment this 
      self.complete() 
     }) 
    } 

    func complete() { //can't move this routine inside block, part of parent class api 
     println("received callback after 5 sec") 
    } 
} 

class AnotherObject { 

    var callback: (() ->())? 

    init() {} 

    func asyncCall(callback:() ->()) { 
     self.callback = callback 

     let delay = 5 * Double(NSEC_PER_SEC) 
     let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) 

     dispatch_after(time, dispatch_get_main_queue(), { [unowned self] in 
      self.callback!() 
     }) 
    } 
} 

var anotherObject = AnotherObject() //not global object but permanent lived 

for i in 1...3 { //can't change here, it's part of API that instantiates my objects 
    var instance = SomeObject() //short lived objects 
    instance.go() 
} 

回答

1

請確認,我不應該在這裏

使用[unowned self]沒有必要與內存管理,擔心自己僅僅因爲一個匿名函數提到self

如果提到self一個匿名函數將會是self的屬性,然後有一個保留週期和潛在的內存泄漏,你應該與內存管理關心自己。通過實施deinit進行記錄,您可以輕鬆查看是否有內存泄漏;如果當你預計這個對象被破壞時它不記錄,它就會泄漏。如果泄漏,您可以嘗試使用[weak self],而不是[unowned self]unowned更方便,但只能在非常有限的情況下使用。

但是,我沒有看到證據表明將保留回調的對象與其中引用的對象相同,如self。它在我看來更像是相反的:你似乎在每個匿名函數上都使用了[unowned self],顯然沒有半點知道你在做什麼。這是非常危險的。除非你知道如何去做,否則你不應該干涉內存管理。我的建議是,你首先刪除代碼中的每一個unowned。然後執行deinit並查看是否有任何實際泄漏的物體。我敢打賭你沒有。

+0

deinit日誌的東西真的把它的神祕 – user2727195