Skip to content

Instantly share code, notes, and snippets.

@RoyalIcing
Last active August 29, 2015 14:26
Show Gist options
  • Save RoyalIcing/96510d2a415eb2c76bae to your computer and use it in GitHub Desktop.
Save RoyalIcing/96510d2a415eb2c76bae to your computer and use it in GitHub Desktop.
//: Property Observing
// Swift 1.2
import Cocoa
import XCPlayground
protocol ObjectListenerType {
func objectDidChange<T: AnyObject>(x: T)
}
protocol ModelType: Reflectable {
typealias Properties
var properties: Properties { get set }
}
class DBStore: ObjectListenerType {
var foregroundQueue: dispatch_queue_t
private var pendingObjectIdentifiers = Set<ObjectIdentifier>()
init(foregroundQueue: dispatch_queue_t = dispatch_get_main_queue()) {
self.foregroundQueue = foregroundQueue
}
func processChangedObject<T: AnyObject>(x: T) {
// Only allow objects to be record once
let identifier = ObjectIdentifier(x)
if (pendingObjectIdentifiers.contains(identifier)) {
pendingObjectIdentifiers.remove(identifier)
recordObject(x)
}
}
func recordObject<T: AnyObject>(x: T) {
let mirror = reflect(x)
for i in 0..<mirror.count {
let (propertyName, propertyMirror) = mirror[i]
println(propertyName)
println(propertyMirror.value)
}
}
func objectDidChange<T: AnyObject>(x: T) {
pendingObjectIdentifiers.insert(ObjectIdentifier(x))
dispatch_async(foregroundQueue) {
self.processChangedObject(x)
}
}
}
class Model<T>: ModelType {
typealias Properties = T
let store: ObjectListenerType
init(store: ObjectListenerType, properties: Properties) {
self.store = store
self.properties = properties
}
var properties: Properties {
didSet {
store.objectDidChange(self)
}
}
func getMirror() -> MirrorType {
return reflect(properties)
}
}
struct Tweet {
var username: String
var message: String
var datePosted: NSDate
}
let store = DBStore()
let tweet = Tweet(username: "brentsimmons", message: "Swift and changes to properties: a feature request. http://inessential.com/2015/08/07/swift_diary_10_changes_to_properties", datePosted: NSDate())
let tweetModel = Model(store: store, properties: tweet)
// Changing two values, which will send two objectDidChange()
// The DBStore will queue, optimally processing the changes once.
tweetModel.properties.message = "Foo bar"
tweetModel.properties.datePosted = NSDate(timeIntervalSinceNow: 200000)
// Allow dispatch_async
XCPSetExecutionShouldContinueIndefinitely()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment