Merge pull request #9 from TouchInstinct/feature/objects_generator

Feature/objects generator
This commit is contained in:
Nikolai Ashanin 2016-02-20 15:52:27 +03:00
commit ca6578c611
9 changed files with 202 additions and 37 deletions

View File

@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
7830C4151C6B337D00180D02 /* CocoaLumberjack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7830C4141C6B337D00180D02 /* CocoaLumberjack.framework */; };
78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */; };
78A74EAD1C6B408C00FE9724 /* ViewModelBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78A74EAC1C6B408C00FE9724 /* ViewModelBuilderProtocol.swift */; };
78B0FC7D1C6B2BE200358B64 /* LogFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */; };
78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7E1C6B2C4D00358B64 /* Log.swift */; };
78B0FC811C6B2CD500358B64 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC801C6B2CD500358B64 /* App.swift */; };
@ -27,6 +26,9 @@
78CFEE591C5C45E500F50370 /* StoryboardIdentifierProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE4E1C5C45E500F50370 /* StoryboardIdentifierProtocol.swift */; };
78CFEE5A1C5C45E500F50370 /* ViewHeightProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE4F1C5C45E500F50370 /* ViewHeightProtocol.swift */; };
78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */; };
78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */; };
78E59B1B1C77470A00C6BFE9 /* TableViewCellsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E59B1A1C77470A00C6BFE9 /* TableViewCellsGenerator.swift */; };
78E59B2A1C7861AF00C6BFE9 /* TableController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E59B291C7861AF00C6BFE9 /* TableController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -41,8 +43,7 @@
/* Begin PBXFileReference section */
7830C4141C6B337D00180D02 /* CocoaLumberjack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaLumberjack.framework; path = Carthage/Build/iOS/CocoaLumberjack.framework; sourceTree = SOURCE_ROOT; };
78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+DefaultNibName.swift"; sourceTree = "<group>"; };
78A74EAC1C6B408C00FE9724 /* ViewModelBuilderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewModelBuilderProtocol.swift; sourceTree = "<group>"; };
78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+DefaultNibName.swift"; path = "LeadKit/Extensions/UIView/UIView+DefaultNibName.swift"; sourceTree = SOURCE_ROOT; };
78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogFormatter.swift; sourceTree = "<group>"; };
78B0FC7E1C6B2C4D00358B64 /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
78B0FC801C6B2CD500358B64 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
@ -53,9 +54,9 @@
78CFEE391C5C456B00F50370 /* LeadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeadKitTests.swift; sourceTree = "<group>"; };
78CFEE3B1C5C456B00F50370 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
78CFEE451C5C45E500F50370 /* UIStoryboard+InstantiateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+InstantiateViewController.swift"; sourceTree = "<group>"; };
78CFEE461C5C45E500F50370 /* UITableView+CellRegistration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+CellRegistration.swift"; sourceTree = "<group>"; };
78CFEE471C5C45E500F50370 /* UITableView+DequeueCustomCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+DequeueCustomCell.swift"; sourceTree = "<group>"; };
78CFEE481C5C45E500F50370 /* UIView+LoadFromNib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+LoadFromNib.swift"; sourceTree = "<group>"; };
78CFEE461C5C45E500F50370 /* UITableView+CellRegistration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UITableView+CellRegistration.swift"; path = "LeadKit/Extensions/UITableView/UITableView+CellRegistration.swift"; sourceTree = SOURCE_ROOT; };
78CFEE471C5C45E500F50370 /* UITableView+DequeueCustomCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UITableView+DequeueCustomCell.swift"; path = "LeadKit/Extensions/UITableView/UITableView+DequeueCustomCell.swift"; sourceTree = SOURCE_ROOT; };
78CFEE481C5C45E500F50370 /* UIView+LoadFromNib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+LoadFromNib.swift"; path = "LeadKit/Extensions/UIView/UIView+LoadFromNib.swift"; sourceTree = SOURCE_ROOT; };
78CFEE4A1C5C45E500F50370 /* NibNameProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibNameProtocol.swift; sourceTree = "<group>"; };
78CFEE4B1C5C45E500F50370 /* ReuseIdentifierProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReuseIdentifierProtocol.swift; sourceTree = "<group>"; };
78CFEE4C1C5C45E500F50370 /* StaticNibNameProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticNibNameProtocol.swift; sourceTree = "<group>"; };
@ -63,6 +64,9 @@
78CFEE4E1C5C45E500F50370 /* StoryboardIdentifierProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardIdentifierProtocol.swift; sourceTree = "<group>"; };
78CFEE4F1C5C45E500F50370 /* ViewHeightProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewHeightProtocol.swift; sourceTree = "<group>"; };
78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewModelProtocol.swift; sourceTree = "<group>"; };
78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectsGenerator.swift; sourceTree = "<group>"; };
78E59B1A1C77470A00C6BFE9 /* TableViewCellsGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCellsGenerator.swift; sourceTree = "<group>"; };
78E59B291C7861AF00C6BFE9 /* TableController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -96,6 +100,8 @@
78A74EAA1C6B401800FE9724 /* Classes */ = {
isa = PBXGroup;
children = (
78E59B281C78613B00C6BFE9 /* TableView */,
78E59B171C773E9600C6BFE9 /* Cache */,
78B0FC7B1C6B2BAE00358B64 /* Logging */,
);
path = Classes;
@ -154,11 +160,9 @@
78CFEE441C5C45E500F50370 /* Extensions */ = {
isa = PBXGroup;
children = (
78E59B2C1C786CD500C6BFE9 /* UIView */,
78E59B2B1C786CBF00C6BFE9 /* UITableView */,
78CFEE451C5C45E500F50370 /* UIStoryboard+InstantiateViewController.swift */,
78CFEE461C5C45E500F50370 /* UITableView+CellRegistration.swift */,
78CFEE471C5C45E500F50370 /* UITableView+DequeueCustomCell.swift */,
78CFEE481C5C45E500F50370 /* UIView+LoadFromNib.swift */,
78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -173,11 +177,45 @@
78CFEE4D1C5C45E500F50370 /* StaticViewHeightProtocol.swift */,
78CFEE4F1C5C45E500F50370 /* ViewHeightProtocol.swift */,
78CFEE501C5C45E500F50370 /* ViewModelProtocol.swift */,
78A74EAC1C6B408C00FE9724 /* ViewModelBuilderProtocol.swift */,
);
path = Protocols;
sourceTree = "<group>";
};
78E59B171C773E9600C6BFE9 /* Cache */ = {
isa = PBXGroup;
children = (
78E59B181C773EE600C6BFE9 /* ObjectsGenerator.swift */,
78E59B1A1C77470A00C6BFE9 /* TableViewCellsGenerator.swift */,
);
path = Cache;
sourceTree = "<group>";
};
78E59B281C78613B00C6BFE9 /* TableView */ = {
isa = PBXGroup;
children = (
78E59B291C7861AF00C6BFE9 /* TableController.swift */,
);
path = TableView;
sourceTree = "<group>";
};
78E59B2B1C786CBF00C6BFE9 /* UITableView */ = {
isa = PBXGroup;
children = (
78CFEE461C5C45E500F50370 /* UITableView+CellRegistration.swift */,
78CFEE471C5C45E500F50370 /* UITableView+DequeueCustomCell.swift */,
);
path = UITableView;
sourceTree = "<group>";
};
78E59B2C1C786CD500C6BFE9 /* UIView */ = {
isa = PBXGroup;
children = (
78CFEE481C5C45E500F50370 /* UIView+LoadFromNib.swift */,
78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */,
);
path = UIView;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -340,16 +378,18 @@
78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */,
78CFEE571C5C45E500F50370 /* StaticNibNameProtocol.swift in Sources */,
78CFEE531C5C45E500F50370 /* UITableView+DequeueCustomCell.swift in Sources */,
78E59B1B1C77470A00C6BFE9 /* TableViewCellsGenerator.swift in Sources */,
78B0FC811C6B2CD500358B64 /* App.swift in Sources */,
78E59B2A1C7861AF00C6BFE9 /* TableController.swift in Sources */,
78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */,
78CFEE511C5C45E500F50370 /* UIStoryboard+InstantiateViewController.swift in Sources */,
78CFEE561C5C45E500F50370 /* ReuseIdentifierProtocol.swift in Sources */,
78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */,
78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */,
78CFEE5A1C5C45E500F50370 /* ViewHeightProtocol.swift in Sources */,
78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */,
78CFEE581C5C45E500F50370 /* StaticViewHeightProtocol.swift in Sources */,
78CFEE591C5C45E500F50370 /* StoryboardIdentifierProtocol.swift in Sources */,
78A74EAD1C6B408C00FE9724 /* ViewModelBuilderProtocol.swift in Sources */,
78B0FC7D1C6B2BE200358B64 /* LogFormatter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -0,0 +1,59 @@
//
// ObjectsPool.swift
// LeadKit
//
// Created by Иван Смолин on 19/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/// class that generates objects on initialization phase and then return its when necessary
public class ObjectsGenerator<T> {
private var objects = [T]()
private let poolSize: UInt
typealias ObjectConstructor = () -> T
private let objectsContructor: ObjectConstructor
private let serialQueue = dispatch_queue_create("ru.touchin.LeadKit.ObjectsGenerator<\(T.self)>", DISPATCH_QUEUE_SERIAL)
/**
initializer function
- parameter poolSize: number of objects to generate
- parameter contructor: objects constructor closure
- returns: nothing
*/
init(poolSize: UInt, objectsContructor contructor: ObjectConstructor) {
self.poolSize = poolSize
self.objectsContructor = contructor
fillPool()
}
private func fillPool() {
for _ in 0..<poolSize {
objects.append(objectsContructor())
}
}
/**
method which returns object from pool
- returns: object from pool
*/
public func get() -> T {
dispatch_sync(serialQueue) {
if self.objects.count < 1 {
self.fillPool()
}
}
return objects.popLast()!
}
}

View File

@ -0,0 +1,26 @@
//
// TableViewCellsPool.swift
// LeadKit
//
// Created by Иван Смолин on 19/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/// class that generates table view cells on initialization phase and then return its when necessary
public class TableViewCellsGenerator<T where T: UITableViewCell>: ObjectsGenerator<T> {
/**
initializer function
- parameter poolSize: number of cells to generate
- parameter cellNibName: cell nib name
- returns: nothing
*/
init(poolSize: UInt, cellNibName: String) {
super.init(poolSize: poolSize, objectsContructor: {() -> T in
T.loadFromNib(named: cellNibName)
})
}
}

View File

@ -0,0 +1,63 @@
//
// TableViewController.swift
// LeadKit
//
// Created by Иван Смолин on 20/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import UIKit
/// abstract class which holds few behaviour configuration properties,
/// inherit and add conformance for table view data source and delegate protocols
public class TableController: NSObject, UITableViewDataSource, UITableViewDelegate {
/**
enumeration which describes how to calculate and store view models for cells
- Precalculated: precacalculate view models for all cells and keep it in memory
- OnTheFlight: calculate view models when needed and forget it immideatelly
- OnTheFlightWithCache: calculate view models when needed and cache it
*/
internal enum TableControllerViewModelCalculationType {
case Precalculated
case OnTheFlight
case OnTheFlightWithCache
}
/**
enumeration which describes how to create cells
- Preloaded: load some amount of cells before data source delegate calls
- OnTheFlight: let table view deside when to load cells
*/
internal enum TableControllerCellCreationType {
case Preloaded
case OnTheFlight
}
internal let viewModelCalculationType: TableControllerViewModelCalculationType
internal let cellCreationType: TableControllerCellCreationType
internal init(viewModelCalculationType calculationType: TableControllerViewModelCalculationType = .OnTheFlight,
cellCreationType creationType: TableControllerCellCreationType = .OnTheFlight) {
self.viewModelCalculationType = calculationType
self.cellCreationType = creationType
super.init()
}
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
preconditionFailure("subclass should implement \(__FUNCTION__)")
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
preconditionFailure("subclass should implement \(__FUNCTION__)")
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
preconditionFailure("subclass should implement \(__FUNCTION__)")
}
}

View File

@ -6,7 +6,7 @@
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
import UIKit
extension UIView: StaticNibNameProtocol {
/**
@ -15,7 +15,7 @@ extension UIView: StaticNibNameProtocol {
- returns: class name string without dot (last class path component)
*/
public static func nibName() -> String {
public class func nibName() -> String {
return NSStringFromClass(self).componentsSeparatedByString(".").last!
}

View File

@ -1,23 +0,0 @@
//
// ViewModelBuilderProtocol.swift
// LeadKit
//
// Created by Иван Смолин on 10/02/16.
// Copyright © 2016 Touch Instinct. All rights reserved.
//
import Foundation
/**
* protocol which declares required methods for view model builder
*/
protocol ViewModelBuilderProtocol {
typealias ViewModelType
/**
method which returns new view model
- returns: view model object
*/
func buildViewModel() -> ViewModelType
}