3

I have a retain cycle when defining a closure as a variable.

The variable is defined as below:

public class MyCell: UICollectionViewCell {
    public var callback: ((MyCell)->Void)?
}

If I use delegates instead of closures, the retain cycle disappears, but I would like to know how can it be defined with closures for future cases.

I tried to set callback variable as weak, but, as I suppose, weak attribute can only be applied to class and class-bound protocol types.

EDIT

Usage:

class CustomController: UIViewController {
   private func onActionOccurs(_ cell: MyCell) {
       cell.backgroundColor = .red // For example
   }

   // After dequeuing the cell:
   {
       cell.callback = onActionOccurs(_:)
   }
}

Thanks

Alberto García
  • 340
  • 3
  • 12

1 Answers1

6

If you don't need to use self, then you can use the cell itself, and modifying your closure implementation in cell like this

public class MyCell: UICollectionViewCell {
    public var callback: (()->Void)?
}

then you can use it, like this example

class CustomController: UIViewController {
   private func onActionOccurs(_ cell: MyCell) {
       cell.backgroundColor = .red // For example
   }

   // After dequeuing the cell:
   {
       cell.callback = {
         cell.backgroundColor = .red // For example
        }
   }
}

but if you need to use a ViewController method then you need to use the [weak self] capture list If you need use UIViewController methods

class CustomController: UIViewController {
   private func onActionOccurs(_ cell: MyCell) {
       cell.backgroundColor = .red // For example
   }

   // After dequeuing the cell:
   {
       cell.callback = { [weak self] in
         guard let self = self else { return }

         self.viewControllerMethod()
        }
   }
}
Marko
  • 2,778
  • 2
  • 10
  • 19
Reinier Melian
  • 20,519
  • 3
  • 38
  • 55
  • Anyone knows why it stays in memory if we use like this? `cell.callback = onActionOccurs(_:)` . I understand that it uses self for somecases but some are not using even self functions or methods. Still stay if we don't use like Reinier's. – flyingBear Sep 18 '18 at 13:17
  • Because if you use `cell.callback = onActionOccurs(_:)`, cell will hold the reference from UIViewController, it is a retain cycle. Reinier's idea callback is holding a closure in stack memory only, it will be destroyed after function call. – Weidian Huang Dec 20 '19 at 03:01