fixed memory leak

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-08-15 09:03:35 -05:00
parent 1b4d40f67e
commit 92ccbbeceb

View File

@ -11,13 +11,13 @@ import Combine
import VDS import VDS
struct User { struct User {
var firstName: String var firstName: String
var lastName: String var lastName: String
init(firstName: String, lastName: String) { init(firstName: String, lastName: String) {
self.firstName = firstName self.firstName = firstName
self.lastName = lastName self.lastName = lastName
} }
} }
public protocol Bindable { public protocol Bindable {
@ -34,17 +34,21 @@ extension Bindable {
} }
class TextFieldBindingCell: UIView, Bindable { class TextFieldBindingCell: UIView, Bindable {
deinit {
print("\(Self.self) deinit")
}
//bindable //bindable
var model: User var model: User
var subject: CurrentValueSubject<User, Never>? var subject: CurrentValueSubject<User, Never>?
let firstNameTextField = TextField() let firstNameTextField = TextField()
let lastNameTextField = TextField() let lastNameTextField = TextField()
init(model: User) { init(model: User) {
self.model = model self.model = model
super.init(frame: .zero) super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false translatesAutoresizingMaskIntoConstraints = false
firstNameTextField.translatesAutoresizingMaskIntoConstraints = false firstNameTextField.translatesAutoresizingMaskIntoConstraints = false
lastNameTextField.translatesAutoresizingMaskIntoConstraints = false lastNameTextField.translatesAutoresizingMaskIntoConstraints = false
@ -52,20 +56,20 @@ class TextFieldBindingCell: UIView, Bindable {
addSubview(firstNameTextField) addSubview(firstNameTextField)
addSubview(lastNameTextField) addSubview(lastNameTextField)
print("\(model.firstName) \(model.lastName)") print("\(model.firstName) \(model.lastName)")
firstNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true firstNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
firstNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true firstNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
firstNameTextField.topAnchor.constraint(equalTo: topAnchor).isActive = true firstNameTextField.topAnchor.constraint(equalTo: topAnchor).isActive = true
firstNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true firstNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
lastNameTextField.topAnchor.constraint(equalTo: firstNameTextField.bottomAnchor, constant: 20).isActive = true lastNameTextField.topAnchor.constraint(equalTo: firstNameTextField.bottomAnchor, constant: 20).isActive = true
lastNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true lastNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
lastNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true lastNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
lastNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true lastNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
lastNameTextField.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true lastNameTextField.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
@ -73,23 +77,25 @@ class TextFieldBindingCell: UIView, Bindable {
func createBinding(with subject: CurrentValueSubject<User, Never>, storeIn subscriptions: inout Set<AnyCancellable>) { func createBinding(with subject: CurrentValueSubject<User, Never>, storeIn subscriptions: inout Set<AnyCancellable>) {
self.model = subject.value self.model = subject.value
self.subject = subject self.subject = subject
//add the logic //add the logic
let firstNameSubject = CurrentValueSubject<String, Never>(model.firstName) let firstNameSubject = CurrentValueSubject<String, Never>(model.firstName)
firstNameTextField.createBinding(with: firstNameSubject, storeIn: &subscriptions) firstNameTextField.createBinding(with: firstNameSubject, storeIn: &subscriptions)
firstNameSubject.assign(to: \.model.firstName, on: self).store(in: &subscriptions) firstNameSubject
firstNameSubject.sink {[weak self] value in .sink {[weak self] value in
self?.send() guard let self = self else { return }
}.store(in: &subscriptions) self.model.firstName = value
self.send()
}.store(in: &subscriptions)
let lastNameSubject = CurrentValueSubject<String, Never>(model.lastName) let lastNameSubject = CurrentValueSubject<String, Never>(model.lastName)
lastNameTextField.createBinding(with: lastNameSubject, storeIn: &subscriptions) lastNameTextField.createBinding(with: lastNameSubject, storeIn: &subscriptions)
lastNameSubject.assign(to: \.model.lastName, on: self).store(in: &subscriptions) lastNameSubject
lastNameSubject.sink {[weak self] value in .sink {[weak self] value in
guard let self = self else { return } guard let self = self else { return }
self.send() self.model.lastName = value
}.store(in: &subscriptions) self.send()
}.store(in: &subscriptions)
} }
} }
@ -97,7 +103,7 @@ class TextFieldBindingCell: UIView, Bindable {
var user = User(firstName: "Joe", lastName: "User") var user = User(firstName: "Joe", lastName: "User")
private var subscriptions = Set<AnyCancellable>() private var subscriptions = Set<AnyCancellable>()
required init() { required init() {
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
} }
@ -111,7 +117,11 @@ class TextFieldBindingCell: UIView, Bindable {
view.backgroundColor = .white view.backgroundColor = .white
let subject = CurrentValueSubject<User, Never>(user) let subject = CurrentValueSubject<User, Never>(user)
subject.assign(to: \.user, on: self).store(in: &subscriptions) subject
.sink{ [weak self] updatedModel in
self?.user = updatedModel
}
.store(in: &subscriptions)
let nameTextField = TextFieldBindingCell(model: user) let nameTextField = TextFieldBindingCell(model: user)
nameTextField.createBinding(with: subject, storeIn: &subscriptions) nameTextField.createBinding(with: subject, storeIn: &subscriptions)
@ -151,7 +161,7 @@ extension UITextField {
} }
public func createBinding(with subject: CurrentValueSubject<String, Never>, public func createBinding(with subject: CurrentValueSubject<String, Never>,
storeIn subscriptions: inout Set<AnyCancellable>) { storeIn subscriptions: inout Set<AnyCancellable>) {
subject.sink { [weak self] (value) in subject.sink { [weak self] (value) in
if value != self?.text { if value != self?.text {
@ -174,14 +184,14 @@ class TextField: UITextField {
bottom: 10, bottom: 10,
right: 20 right: 20
) )
override func textRect(forBounds bounds: CGRect) -> CGRect { override func textRect(forBounds bounds: CGRect) -> CGRect {
layer.borderColor = UIColor.black.cgColor layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1 layer.borderWidth = 1
let rect = super.textRect(forBounds: bounds) let rect = super.textRect(forBounds: bounds)
return rect.inset(by: textPadding) return rect.inset(by: textPadding)
} }
override func editingRect(forBounds bounds: CGRect) -> CGRect { override func editingRect(forBounds bounds: CGRect) -> CGRect {
layer.borderColor = UIColor.black.cgColor layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1 layer.borderWidth = 1