2016-08-25 27 views
1

的ViewController代碼我應該讓自定義單元的委託作爲弱引用的proprety嗎?

class ViewController: UIViewController { 
    deinit { 
     print("ViewController deinitialised") 
    } 

    @IBOutlet weak var tableView: UITableView! 

    override func viewDidLoad() { 
     self.tableView.dataSource = self 
    } 

    func didTapBlue() { 

    } 
} 

extension ViewController: UITableViewDataSource, CustomCellDelegate { 
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 5 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("myCell") as! CustomCell 
     cell.delegate = self 
     cell.textLabel!.text = "\(indexPath.row)" 
     return cell 
    } 

    func buttonTapped() { 
     print("Button tapped") 
    } 
} 

CustomCell代碼

class CustomCell: UITableViewCell { 
    deinit { 
     print("Cell deinitialised") 
    } 

    var delegate: CustomCellDelegate! //When protocol Type is A 
    // weak prefix when protocol Type is B 
    // weak var delegate: CustomCellDelegate! 

    @IBAction func buttonClickAction(sender: AnyObject) { 
     if let del = self.delegate { 
      del.buttonTapped() 
     } 
    } 
} 

協議類型A

protocol CustomCellDelegate{ 
    func buttonTapped() 
} 

協議類型B

protocol CustomCellDelegate: class { 
    func buttonTapped() 
} 

我很困惑在Cell和ViewController之間傳遞消息的實現委託模式的適當方式是什麼。我知道,如果兩個對象強烈地保持彼此的引用,將會有一個保留週期,並且在應用程序生命週期中它們不會被釋放。

在上面的代碼中,ViewController似乎沒有保存Cell的引用。因此,我認爲使用類型A的協議並將ViewController的強引用保存在單元格中並不重要。

但是如果我將委託屬性聲明爲弱引用屬性,我的代碼會更安全嗎?它有什麼含義?

更新:

事實證明,即使是的ViewController未持有細胞&即使TableView中的引用是弱的直接引用,視圖控制器以某種方式持有強引用的單元格。當我遵循方法A時,那是沒有聲明代表是弱引用的。 Cell和ViewController中的deinit方法永遠不會被調用。我也檢查過儀器。如果我不聲明委託人弱,持續保留計數會不斷增加。

enter image description here

現在最大的問題是視圖控制器是如何保持強引用單元格?

+0

我認爲真正的問題是單元格之前的一步:什麼是具有強參考的@IBOutlet?如果它是ViewController,它如何在內部管理保留週期? –

+0

再次用完整的ViewController代碼更新。 –

回答

0

去初始化流程:

當視圖控制器被彈出。 然後調用deinit方法。

然後只清除視圖控制器持有的所有其他引用。

父母deinit觸發器,然後子終止觸發器然後終於遍歷通過然後釋放父母終於終於做。

如果任何孩子強烈引用父母。父母的決定永遠不會被調用,並且所有的非初始化過程都將停止。在我們的例子中,因爲cell牢牢地保留了視圖控制器。 ViewController的deinit方法永遠不會被調用。因此保留週期。 以下是對retain cycle.的很好的解釋

1

有幾件事情在那裏。

  1. 使每一個視圖控制器符合的UITableViewDelegate和UITableViewDatasource不用,因爲你已經擁有的UITableViewController,你可能會需要反正覆蓋這些方法。您會在開發生命週期的某個時間點複製代碼。

  2. 代表總是需要一個弱的參考來避免保留週期。

+0

另請注意,由於'buttonTapped'不能傳遞自己,因此知道點擊哪個按鈕並不容易。 –

+0

@MatthewSeaman你說得對。這很難說,但是再次......他可能需要重寫整個實現。 –

+1

我在這裏展示的代碼僅用於演示目的。請參閱上述更新。 –

相關問題