Skip to content

Commit

Permalink
makes DTTableViewManager property optional to prevent crashes on iOS 10.
Browse files Browse the repository at this point in the history
  • Loading branch information
DenTelezhkin committed Oct 5, 2017
1 parent 08d5725 commit dc84f49
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.

# Next

* Makes `DTTableViewManager` property weak instead of unowned to prevent iOS 10-specific memory issues/crashes.

## [6.0.0-beta.2](https://github.com/DenHeadless/DTTableViewManager/releases/tag/6.0.0-beta.2)

* Build with Xcode 9.0 final release.
Expand Down
12 changes: 6 additions & 6 deletions Source/DTTableViewDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ open class DTTableViewDataSource : DTTableViewDelegateWrapper, UITableViewDataSo
}

open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.storage.sections[section].numberOfItems
return storage?.sections[section].numberOfItems ?? 0
}

open func numberOfSections(in tableView: UITableView) -> Int {
return self.storage.sections.count
return storage?.sections.count ?? 0
}

open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let model = self.storage.item(at: indexPath) else {
guard let model = storage?.item(at: indexPath) else {
return UITableViewCell()
}

let cell : UITableViewCell
do {
cell = try self.viewFactory.cellForModel(model, atIndexPath: indexPath)
cell = try viewFactory?.cellForModel(model, atIndexPath: indexPath) ?? UITableViewCell()
} catch let error as DTTableViewFactoryError {
handleTableViewFactoryError(error)
cell = UITableViewCell()
Expand All @@ -63,13 +63,13 @@ open class DTTableViewDataSource : DTTableViewDelegateWrapper, UITableViewDataSo
}

open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if configuration.sectionHeaderStyle == .view { return nil }
if configuration?.sectionHeaderStyle == .view { return nil }

return self.headerModel(forSection: section) as? String
}

open func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
if configuration.sectionFooterStyle == .view { return nil }
if configuration?.sectionFooterStyle == .view { return nil }

return self.footerModel(forSection: section) as? String
}
Expand Down
16 changes: 8 additions & 8 deletions Source/DTTableViewDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate
open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
defer { (delegate as? UITableViewDelegate)?.tableView?(tableView, willDisplay: cell, forRowAt: indexPath) }
guard let model = storage.item(at: indexPath) else { return }
guard let model = storage?.item(at: indexPath) else { return }
_ = tableViewEventReactions.performReaction(of: .cell, signature: EventMethodSignature.willDisplayCellForRowAtIndexPath.rawValue, view: cell, model: model, location: indexPath)
}

Expand All @@ -53,12 +53,12 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate
}

open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if configuration.sectionHeaderStyle == .title { return nil }
if configuration?.sectionHeaderStyle == .title { return nil }

if let model = self.headerModel(forSection:section) {
let view : UIView?
do {
view = try self.viewFactory.headerViewForModel(model, atIndexPath: IndexPath(index: section))
view = try viewFactory?.headerViewForModel(model, atIndexPath: IndexPath(index: section))
} catch let error as DTTableViewFactoryError {
handleTableViewFactoryError(error)
view = nil
Expand All @@ -78,12 +78,12 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate
}

open func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if configuration.sectionFooterStyle == .title { return nil }
if configuration?.sectionFooterStyle == .title { return nil }

if let model = self.footerModel(forSection: section) {
let view : UIView?
do {
view = try self.viewFactory.footerViewForModel(model, atIndexPath: IndexPath(index: section))
view = try viewFactory?.footerViewForModel(model, atIndexPath: IndexPath(index: section))
} catch let error as DTTableViewFactoryError {
handleTableViewFactoryError(error)
view = nil
Expand All @@ -109,7 +109,7 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate
if let height = (delegate as? UITableViewDelegate)?.tableView?(tableView, heightForHeaderInSection: section) {
return height
}
if configuration.sectionHeaderStyle == .title {
if configuration?.sectionHeaderStyle == .title {
if let _ = self.headerModel(forSection:section)
{
return UITableViewAutomaticDimension
Expand Down Expand Up @@ -138,7 +138,7 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate
if let height = (delegate as? UITableViewDelegate)?.tableView?(tableView, heightForFooterInSection: section) {
return height
}
if configuration.sectionFooterStyle == .title {
if configuration?.sectionFooterStyle == .title {
if let _ = self.footerModel(forSection:section) {
return UITableViewAutomaticDimension
}
Expand Down Expand Up @@ -257,7 +257,7 @@ open class DTTableViewDelegate : DTTableViewDelegateWrapper, UITableViewDelegate

open func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
defer { (delegate as? UITableViewDelegate)?.tableView?(tableView, didEndDisplaying: cell, forRowAt: indexPath) }
guard let model = storage.item(at: indexPath) else { return }
guard let model = storage?.item(at: indexPath) else { return }
_ = tableViewEventReactions.performReaction(of: .cell, signature: EventMethodSignature.didEndDisplayingCellForRowAtIndexPath.rawValue, view: cell, model: model, location: indexPath)
}

Expand Down
24 changes: 13 additions & 11 deletions Source/DTTableViewDelegateWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ import DTModelStorage
/// Base class for objects, that implement various datasource and delegate methods from `UITableView`. Even though this class is declared as `open`, subclassing it is discouraged. Please subsclass concrete subclass of this class, such as `DTTableViewDelegate`.
open class DTTableViewDelegateWrapper : NSObject {
weak var delegate: AnyObject?
weak var tableView: UITableView? { return manager.tableView }
var viewFactory: TableViewFactory { return manager.viewFactory }
var storage: Storage { return manager.storage }
var configuration: TableViewConfiguration { return manager.configuration }
weak var tableView: UITableView? { return manager?.tableView }
var viewFactory: TableViewFactory? { return manager?.viewFactory }
var storage: Storage? { return manager?.storage }
var configuration: TableViewConfiguration? { return manager?.configuration }

@available(*, deprecated, message: "Error handling system is deprecated and will be removed in future versions of the framework")
var viewFactoryErrorHandler: ((DTTableViewFactoryError) -> Void)? { return manager.viewFactoryErrorHandler }
private unowned let manager: DTTableViewManager
var viewFactoryErrorHandler: ((DTTableViewFactoryError) -> Void)? { return manager?.viewFactoryErrorHandler }
private weak var manager: DTTableViewManager?

public init(delegate: AnyObject?, tableViewManager: DTTableViewManager) {
self.delegate = delegate
Expand All @@ -62,6 +62,7 @@ open class DTTableViewDelegateWrapper : NSObject {
/// If `TableViewConfiguration` `displayHeaderOnEmptySection` is false, this method also returns nil.
final func headerModel(forSection index: Int) -> Any?
{
guard let storage = storage, let configuration = configuration else { return nil }
guard storage.sections.count > index else { return nil }

if storage.sections[index].numberOfItems == 0 && !configuration.displayHeaderOnEmptySection
Expand All @@ -76,6 +77,7 @@ open class DTTableViewDelegateWrapper : NSObject {
/// If `TableViewConfiguration` `displayFooterOnEmptySection` is false, this method also returns nil.
final func footerModel(forSection index: Int) -> Any?
{
guard let storage = storage, let configuration = configuration else { return nil }
guard storage.sections.count > index else { return nil }

if storage.sections[index].numberOfItems == 0 && !configuration.displayFooterOnEmptySection
Expand Down Expand Up @@ -174,14 +176,14 @@ open class DTTableViewDelegateWrapper : NSObject {
final func performCellReaction(_ signature: EventMethodSignature, location: IndexPath, provideCell: Bool) -> Any? {
var cell : UITableViewCell?
if provideCell { cell = tableView?.cellForRow(at: location) }
guard let model = storage.item(at: location) else { return nil }
guard let model = storage?.item(at: location) else { return nil }
return tableViewEventReactions.performReaction(of: .cell, signature: signature.rawValue, view: cell, model: model, location: location)
}

final func perform4ArgumentCellReaction(_ signature: EventMethodSignature, argument: Any, location: IndexPath, provideCell: Bool) -> Any? {
var cell : UITableViewCell?
if provideCell { cell = tableView?.cellForRow(at: location) }
guard let model = storage.item(at: location) else { return nil }
guard let model = storage?.item(at: location) else { return nil }
return tableViewEventReactions.perform4ArgumentsReaction(of: .cell,
signature: signature.rawValue,
argument: argument,
Expand All @@ -197,7 +199,7 @@ open class DTTableViewDelegateWrapper : NSObject {
provideCell: Bool) -> Any? {
var cell : UITableViewCell?
if provideCell { cell = tableView?.cellForRow(at: location) }
guard let model = storage.item(at: location) else { return nil }
guard let model = storage?.item(at: location) else { return nil }
return tableViewEventReactions.perform5ArgumentsReaction(of: .cell,
signature: signature.rawValue,
firstArgument: argumentOne,
Expand All @@ -210,12 +212,12 @@ open class DTTableViewDelegateWrapper : NSObject {
final func performNillableCellReaction(_ reaction: EventReaction, location: IndexPath, provideCell: Bool) -> Any? {
var cell : UITableViewCell?
if provideCell { cell = tableView?.cellForRow(at: location) }
guard let model = storage.item(at: location) else { return nil }
guard let model = storage?.item(at: location) else { return nil }
return reaction.performWithArguments((cell as Any,model,location))
}

final func cellReaction(_ signature: EventMethodSignature, location: IndexPath) -> EventReaction? {
guard let model = storage.item(at: location) else { return nil }
guard let model = storage?.item(at: location) else { return nil }
return tableViewEventReactions.reaction(of: .cell, signature: signature.rawValue, forModel: model, view: nil)
}

Expand Down

0 comments on commit dc84f49

Please sign in to comment.