Skip to content

Commit d11abbe

Browse files
committed
Use convenience initializers?
Doesn’t work :(
1 parent 25cf3f3 commit d11abbe

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

Sources/SwiftyTimer.swift

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,51 @@
2525
import Foundation
2626

2727
extension NSTimer {
28+
29+
// MARK: Create a timer without scheduling
30+
31+
/// Create a timer that will call `block` once after the specified time.
32+
///
33+
/// - Note: The timer won't fire until it's scheduled on the run loop.
34+
/// Use `NSTimer.after` to create and schedule a timer in one step.
35+
/// - Note: If you support iOS 8 or older, or OS X 10.11 or older, use `NSTimer.new(after:)`
36+
/// instead of this initializer.
37+
38+
@available(iOS 9, OSX 10.11, watchOS 2, tvOS 9, *)
39+
public convenience init(after interval: NSTimeInterval, _ block: () -> Void) {
40+
let actor = Actor { _ in block() }
41+
self.init(timeInterval: interval, target: actor, selector: #selector(Actor.fire), userInfo: nil, repeats: false)
42+
}
43+
44+
/// Create a timer that will call `block` repeatedly in specified time intervals.
45+
///
46+
/// - Note: The timer won't fire until it's scheduled on the run loop.
47+
/// Use `NSTimer.every` to create and schedule a timer in one step.
48+
/// - Note: If you support iOS 8 or older, or OS X 10.11 or older, use `NSTimer.new(every:)`
49+
/// instead of this initializer.
50+
51+
@available(iOS 9, OSX 10.11, watchOS 2, tvOS 9, *)
52+
public convenience init(every interval: NSTimeInterval, _ block: () -> Void) {
53+
let actor = Actor { _ in block() }
54+
self.init(timeInterval: interval, target: actor, selector: #selector(Actor.fire), userInfo: nil, repeats: true)
55+
}
56+
57+
/// Create a timer that will call `block` repeatedly in specified time intervals.
58+
/// (This variant also passes the timer instance to the block)
59+
///
60+
/// - Note: The timer won't fire until it's scheduled on the run loop.
61+
/// Use `NSTimer.every` to create and schedule a timer in one step.
62+
/// - Note: If you support iOS 8 or older, or OS X 10.11 or older, use `NSTimer.new(every:)`
63+
/// instead of this initializer.
64+
65+
@available(iOS 9, OSX 10.11, watchOS 2, tvOS 9, *)
66+
@nonobjc public convenience init(every interval: NSTimeInterval, _ block: NSTimer -> Void) {
67+
let actor = Actor(block)
68+
self.init(timeInterval: interval, target: actor, selector: #selector(Actor.fire), userInfo: nil, repeats: true)
69+
}
70+
71+
// MARK: (Legacy factory methods)
72+
2873
/// Create a timer that will call `block` once after the specified time.
2974
///
3075
/// - Note: The timer won't fire until it's scheduled on the run loop.
@@ -39,7 +84,7 @@ extension NSTimer {
3984
/// Create a timer that will call `block` repeatedly in specified time intervals.
4085
///
4186
/// - Note: The timer won't fire until it's scheduled on the run loop.
42-
/// Use `NSTimer.after` to create and schedule a timer in one step.
87+
/// Use `NSTimer.every` to create and schedule a timer in one step.
4388
/// - Note: The `new` class function is a workaround for a crashing bug when using convenience initializers (rdar://18720947)
4489

4590
public class func new(every interval: NSTimeInterval, _ block: () -> Void) -> NSTimer {
@@ -50,7 +95,7 @@ extension NSTimer {
5095
/// (This variant also passes the timer instance to the block)
5196
///
5297
/// - Note: The timer won't fire until it's scheduled on the run loop.
53-
/// Use `NSTimer.after` to create and schedule a timer in one step.
98+
/// Use `NSTimer.every` to create and schedule a timer in one step.
5499
/// - Note: The `new` class function is a workaround for a crashing bug when using convenience initializers (rdar://18720947)
55100

56101
@nonobjc public class func new(every interval: NSTimeInterval, _ block: NSTimer -> Void) -> NSTimer {

SwiftyTimerTests/SwiftyTimerTests/main.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
8181
NSTimer.after(0.1.seconds, test8)
8282
}
8383

84+
// repeats with NSTimer passed in
85+
8486
func test8() {
8587
var fires = 0
8688
let timer = NSTimer.new(every: 0.1.seconds) { (timer: NSTimer) in
@@ -101,11 +103,63 @@ class AppDelegate: NSObject, NSApplicationDelegate {
101103
guard fires <= 1 else { fatalError("should be invalidated") }
102104
defer { fires += 1 }
103105

106+
if fires == 1 {
107+
timer.invalidate()
108+
109+
if #available(OSX 10.11, *) {
110+
self.test10()
111+
} else {
112+
self.done()
113+
}
114+
}
115+
}
116+
}
117+
118+
// init() syntax
119+
120+
@available(OSX 10.11, *)
121+
func test10() {
122+
var fired = false
123+
let timer = NSTimer(after: 0.1.seconds) {
124+
guard !fired else { fatalError("should only be called once") }
125+
defer { fired = true }
126+
127+
self.test11()
128+
fired = true
129+
}
130+
131+
timer.start()
132+
}
133+
134+
@available(OSX 10.11, *)
135+
func test11() {
136+
var fires = 0
137+
var timer: NSTimer!
138+
timer = NSTimer(every: 0.1.seconds) {
139+
guard fires <= 1 else { fatalError("should be invalidated") }
140+
defer { fires += 1 }
141+
142+
if fires == 1 {
143+
timer.invalidate()
144+
self.test12()
145+
}
146+
}
147+
timer.start()
148+
}
149+
150+
@available(OSX 10.11, *)
151+
func test12() {
152+
var fires = 0
153+
let timer = NSTimer(every: 0.1.seconds) { (timer: NSTimer) in
154+
guard fires <= 1 else { fatalError("should be invalidated") }
155+
defer { fires += 1 }
156+
104157
if fires == 1 {
105158
timer.invalidate()
106159
self.done()
107160
}
108161
}
162+
timer.start()
109163
}
110164

111165
func done() {

0 commit comments

Comments
 (0)