2014-10-02 71 views
2

我正在實現一個非常簡單的表視圖。不知道爲什麼對象被提前解除分配

當創建視圖,該代碼是這樣的:

func selectFolder(path: String) { 
    var folderViewController = UITableViewController() 
    var dataSource = folderViewData(path: path) 
    folderViewController.tableView!.dataSource = dataSource // note I've confirmed that tableView is instantiated at this point 
    navController.pushViewController(folderViewController, animated: true) 
} 

我的數據源是非常簡單; init()如下所示:

class folderViewData: NSObject, UITableViewDataSource, UITableViewDelegate { 

    var rootFolder:String 

    init(path:String) { 
     rootFolder = path 
     DPLog("initializing folderViewDelegate") 
     super.init() 
    } 

    <dataSource methods snipped> 
} 

運行此操作時,由於引用了釋放對象,導致出現錯誤。當我運行儀器尋找殭屍,我得到這個錯誤:

An Objective-C message was sent to a deallocated 'dpScheme.folderViewData' object (zombie) at address: 0x7ff6516f5cf0.

我無法弄清楚如何獲得儀器信息以純文本的,我沒有足夠的信譽發表圖片。簡短的描述是,「selectFolder」方法保留「folderViewData」一次並釋放兩次。

任何人都可以幫忙嗎?

謝謝,

大衛

回答

0

你需要以某種方式保持你的數據源,並且tableView對它的dataSource屬性的弱引用是不夠的。一旦selectFolder中的局部變量超出範圍,數據源將被解除分配。

這個問題的一個非常常見的解決方案是在該類中放置一個強屬性,其中selectFolder位於該類中,並將該數據源分配給該屬性,以便它將留在該處。

+0

謝謝,我沒有意識到dataSource屬性很弱。將dataSource作爲一個屬性看起來相當麻煩,因爲當用戶瀏覽文件夾層次結構時,會有(可能)其中的幾個。 – 2014-10-02 17:57:04

-1

表視圖具有弱引用的數據源。由於您在數據源中傳遞並且在方法結束後沒有其他對象強制保留它,它將被解除分配。也許子類UITableViewController具有強大的數據源屬性,所以會有強烈的參考。

+0

您絕對不應該繼承子類以使數據源強大。這只是要求在未來發生強大的參考週期。 – Lance 2014-10-02 17:43:14

+0

只是好奇 - 如何?一旦控制器被解除分配,數據源也不會被釋放? – 2014-10-02 18:46:25

+0

在這個特定的情況下,也許。 dataSource屬性由於某個原因而很弱。說別人以後無意中使用了你的子類,並沒有像這樣使用它,你會得到內存泄漏。想想如果呈現視圖控制器是數據源而不是第三個對象會發生什麼。呈現視圖控制器可以(並且最有可能)對呈現的視圖控制器有強烈的參考,現在使用強數據源參考,現在也是如此。從而創建一個強大的參考週期。 – Lance 2014-10-02 18:51:15

相關問題