Last active
August 29, 2015 14:23
-
-
Save MartinJNash/2c856305d63333614015 to your computer and use it in GitHub Desktop.
A Swift class to dispatch blocks either the first time and or all but the first time.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public final class FirstOrAllOtherDispatcher { | |
private var firstTimeOnlyBlock: (()->Void)? | |
private var allOtherTimesBlock: (()->Void)? | |
public init(firstTime: ()->Void) { | |
self.firstTimeOnlyBlock = firstTime | |
self.allOtherTimesBlock = nil | |
} | |
public init(allButFirstBlock: ()->Void) { | |
self.firstTimeOnlyBlock = nil | |
self.allOtherTimesBlock = allButFirstBlock | |
} | |
public init(firstTime: ()->Void, allOtherTimes: ()->Void) { | |
self.firstTimeOnlyBlock = firstTime | |
self.allOtherTimesBlock = allOtherTimes | |
} | |
private var once: dispatch_once_t = 0 | |
private func makeSwizzle() { | |
dispatch_once(&once, { | |
let myclass: AnyClass = object_getClass(self) | |
let originalMethod = class_getInstanceMethod(myclass, "doing") | |
let swizzledMethod = class_getInstanceMethod(myclass, "realDoing") | |
method_exchangeImplementations(originalMethod, swizzledMethod) | |
}) | |
} | |
/// This has to be dynamic, can be private | |
private dynamic func doing() { | |
makeSwizzle() | |
firstTimeOnlyBlock?() | |
} | |
/// Has to be at least internal or be private dynamic | |
private dynamic func realDoing() { | |
allOtherTimesBlock?() | |
} | |
public func call() { | |
doing() | |
} | |
} | |
let tt = FirstOrAllOtherDispatcher(firstTime: { print("Fisrt and once") }, allOtherTimes: { print("Other time") }) | |
tt.call() | |
tt.call() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment