Когда удалять пользовательское событие Click из UITableCellView - PullRequest
0 голосов
/ 16 января 2020

за последние пару дней я оптимизировал свое приложение и обнаружил некоторые утечки памяти. Я реализовал пользовательский UIButton, в котором есть событие publi c, на которое я подписываюсь. На одной UITableViewController кнопка находится в UITableCellView, и я подписываюсь на это событие:

Ячейка:

class SelectionButtonCell : UITableViewCell
{
    @IBOutlet weak var selectionButton: SelectionButton!
    @IBOutlet weak var label: UILabel!
}

UITableViewController:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let selectionButtonCell = tableView.dequeueReusableCell(withIdentifier: "selectionButtonCell") as! SelectionButtonCell
    selectionButtonCell.selectionButton.clicked = // This leaks memory because nowhere in my code this is set to nil
    {
        // Some unimportant stuff.
    }

    return selectionButtonCell
}

Кнопка:

public class SelectionButton : UIButton
{
    // MARK: - Events
    public var clicked: (() -> ())?

    public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
    {
        super.touchesEnded(touches, with: event)

        self.clicked?()
    }
}

Как мне установить эту переменную на ноль? Я не нашел ни одной функции, которая будет вызываться при переходе назад (UITableViewController помещается в UINavigationController). Можно ли просто перебрать все ячейки и установить значение nil в viewWillDisappear(_) или есть более хороший способ?

Я пробовал tableView:didEndDisplayingCell:forRowAtIndexPath, но кажется, что это вызывается только при прокрутке UITableView.

Ответы [ 2 ]

1 голос
/ 16 января 2020

Вам не нужен подкласс UIButton. И вам не нужно IBOutlet

В SelectionButtonCell объявлять IBAction и обратный вызов. Подключите кнопку к действию. В обратном вызове передать ячейку.

class SelectionButtonCell : UITableViewCell
{
    @IBOutlet weak var label: UILabel!

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

    @IBAction func buttonClicked(_ sender : UIButton)
    {
        callback?(self)
    }
}

В celForRow получить текущий indexPath из ячейки

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let selectionButtonCell = tableView.dequeueReusableCell(withIdentifier: "selectionButtonCell") as! SelectionButtonCell
    selectionButtonCell.callback = { buttonCell in
        let actualIndexPath = tableView.indexPath(for: buttonCell)!
        ...
    }

    return selectionButtonCell
}

Если ячейки в виде таблицы не вставлены, удалены или перемещены, вам даже не нужен cell параметр в закрытии обратного вызова. Захваченный параметр indexPath все еще действителен.

1 голос
/ 16 января 2020
 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let selectionButtonCell = tableView.dequeueReusableCell(withIdentifier: "selectionButtonCell") as! SelectionButtonCell
        selectionButtonCell.selectionButton.clicked = 
        { [weak self] in
            // Some unimportant stuff.
        }

        return selectionButtonCell
    }

Также существует несколько способов Получить нажатие кнопки внутри UITableViewCell вы используете замыкание

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...