How to cancel an Asynchronous function in Swift - swift

In swift, what is the common practice to cancel an aync execution?
Using this example, which execute the closure asynchronously,
what is the way to cancel the async function?
func getSumOf(array:[Int], handler: #escaping ((Int)->Void)) {
//step 2
var sum: Int = 0
for value in array {
sum += value
}
//step 3
Globals.delay(0.3, closure: {
handler(sum)
})
}
func doSomething() {
//setp 1
self.getSumOf(array: [16,756,442,6,23]) { [weak self](sum) in
print(sum)
//step 4, finishing the execution
}
}
//Here we are calling the closure with the delay of 0.3 seconds
//It will print the sumof all the passed numbers.

Unfortunately, there is no generalized answer to this question as it depends entirely upon your asynchronous implementation.
Let's imagine that your delay was the typical naive implementation:
static func delay(_ timeInterval: TimeInterval, closure: #escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + timeInterval) {
closure()
}
}
That's not going to be cancelable.
However you can redefine it to use DispatchWorkItem. This is cancelable:
#discardableResult
static func delay(_ timeInterval: TimeInterval, closure: #escaping () -> Void) -> DispatchWorkItem {
let task = DispatchWorkItem {
closure()
}
DispatchQueue.main.asyncAfter(deadline: .now() + timeInterval, execute: task)
return task
}
By making it return a #discardableResult, that means that you can use it like before, but if you want to cancel it, grab the result and pass it along. E.g., you can define your asynchronous sum routine to use this pattern, too:
#discardableResult
func sum(of array: [Int], handler: #escaping (Int) -> Void) -> DispatchWorkItem {
let sum = array.reduce(0, +)
return Globals.delay(3) {
handler(sum)
}
}
Now, doSomething can, if it wants, capture the returned value and use it to cancel the asynchronously scheduled task:
func doSomething() {
var task = sum(of: [16, 756, 442, 6, 23]) { sum in
print(Date(), sum)
}
...
task.cancel()
}
You can also implement the delay with a Timer:
#discardableResult
static func delay(_ timeInterval: TimeInterval, closure: #escaping () -> Void) -> Timer {
Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false) { _ in
closure()
}
}
And
#discardableResult
func sum(of array: [Int], handler: #escaping (Int) -> Void) -> Timer {
let sum = array.reduce(0, +)
return Globals.delay(3) {
handler(sum)
}
}
But this time, you'd invalidate the timer:
func doSomething() {
weak var timer = sum(of: [16, 756, 442, 6, 23]) { sum in
print(Date(), sum)
}
...
timer?.invalidate()
}
It must be noted that the above scenarios are unique to simple “delay” scenarios. This is not a general purpose solution for stopping asynchronous processes. For example, if the asynchronous tasks consists of some time consuming for loop, the above is insufficient.
For example, let's say you are doing something really complicated calculation in a for loop (e.g. processing the pixels of an image, processing frames of a video, etc.). In that case, because there is no preemptive cancelation, you'd need to manually check to see if the DispatchWorkItem or the Operation has been canceled by checking their respective isCancelled properties.
For example, let's consider an operation to sum all primes less than 1 million:
class SumPrimes: Operation {
override func main() {
var sum = 0
for i in 1 ..< 1_000_000 {
if isPrime(i) {
sum += i
}
}
print(Date(), sum)
}
func isPrime(_ value: Int) -> Bool { ... } // this is slow
}
(Obviously, this isn't an efficient way to solve the “sum of primes less than x” problem, but it just an example for illustrative purposes.)
And
let queue = OperationQueue()
let operation = SumPrimes()
queue.addOperation(operation)
We're not going to be able to cancel that. Once it starts, there’s no stopping it.
But we can make it cancelable by adding a check for isCancelled in our loop:
class SumPrimes: Operation {
override func main() {
var sum = 0
for i in 1 ..< 1_000_000 {
if isCancelled { return }
if isPrime(i) {
sum += i
}
}
print(Date(), sum)
}
func isPrime(_ value: Int) -> Bool { ... }
}
And
let queue = OperationQueue()
let operation = SumPrimes()
queue.addOperation(operation)
...
operation.cancel()
Bottom line, if it’s something other than a simple delay, and you want it to be cancelable, you have to integrate this into your code that can be run asynchronously.

Using this example..., what is the way to cancel the async function?
Using that example, there is no such way. The only way to avoid printing the sum is for self to go out existence some time in the 0.3 seconds immediately after the call.
(There are ways to make a cancellable timer, but the timer you've made, assuming that it's the delay I think it is, is not cancellable.)

I don't know your algorithm but first I have suggestions for some points.
If you want to delay, do it outside of getSumOf function for adapt Single Responsibility.
Use built-in reduce function to sum items in array in better and more efficient way.
You can use DispatchWorkItem to build a cancellable task. So you can remove getSumOf function and edit doSomething function like below.
let yourArray = [16,756,442,6,23]
let workItem = DispatchWorkItem {
// Your async code goes in here
let sum = yourArray.reduce(0, +)
print(sum)
}
// Execute the work item after 0.3 second
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: workItem)
// You can cancel the work item if you no longer need it
workItem.cancel()
You can also look into OperationQueue for advanced use.

Related

Why does `Publishers.Map` consume upstream values eagerly?

Suppose I have a custom subscriber that requests one value on subscription and then an additional value three seconds after it receives the previous value:
class MySubscriber: Subscriber {
typealias Input = Int
typealias Failure = Never
private var subscription: Subscription?
func receive(subscription: Subscription) {
print("Subscribed")
self.subscription = subscription
subscription.request(.max(1))
}
func receive(_ input: Int) -> Subscribers.Demand {
print("Value: \(input)")
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
self.subscription?.request(.max(1))
}
return .none
}
func receive(completion: Subscribers.Completion<Never>) {
print("Complete")
subscription = nil
}
}
If I use this to subscribe to an infinite range publisher, back pressure is handled gracefully, with the publisher waiting 3 seconds each time until it receives the next demand to send a value:
(1...).publisher.subscribe(MySubscriber())
// Prints values infinitely with ~3 seconds between each:
//
// Subscribed
// Value: 1
// Value: 2
// Value: 3
// ...
But if I add a map operator then MySubscriber never even receives a subscription; map appears to have synchronously requested Demand.Unlimited upon receiving its subscription and the app infinitely spins as map tries to exhaust the infinite range:
(1...).publisher
.map { value in
print("Map: \(value)")
return value * 2
}
.subscribe(MySubscriber())
// The `map` transform is executed infinitely with no delay:
//
// Map: 1
// Map: 2
// Map: 3
// ...
My question is, why does map behave this way? I would have expected map to just pass its downstream demand to the upstream. Since map is supposed to be for transformation rather than side effects, I don't understand what the use case is for its current behavior.
EDIT
I implemented a version of map to show how I think it ought to work:
extension Publishers {
struct MapLazily<Upstream: Publisher, Output>: Publisher {
typealias Failure = Upstream.Failure
let upstream: Upstream
let transform: (Upstream.Output) -> Output
init(upstream: Upstream, transform: #escaping (Upstream.Output) -> Output) {
self.upstream = upstream
self.transform = transform
}
public func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Upstream.Failure {
let mapSubscriber = Subscribers.LazyMapSubscriber(downstream: subscriber, transform: transform)
upstream.receive(subscriber: mapSubscriber)
}
}
}
extension Subscribers {
class LazyMapSubscriber<Input, DownstreamSubscriber: Subscriber>: Subscriber {
let downstream: DownstreamSubscriber
let transform: (Input) -> DownstreamSubscriber.Input
init(downstream: DownstreamSubscriber, transform: #escaping (Input) -> DownstreamSubscriber.Input) {
self.downstream = downstream
self.transform = transform
}
func receive(subscription: Subscription) {
downstream.receive(subscription: subscription)
}
func receive(_ input: Input) -> Subscribers.Demand {
downstream.receive(transform(input))
}
func receive(completion: Subscribers.Completion<DownstreamSubscriber.Failure>) {
downstream.receive(completion: completion)
}
}
}
extension Publisher {
func mapLazily<Transformed>(transform: #escaping (Output) -> Transformed) -> AnyPublisher<Transformed, Failure> {
Publishers.MapLazily(upstream: self, transform: transform).eraseToAnyPublisher()
}
}
Using this operator, MySubscriber receives the subscription immediately and the mapLazily transform is only executed when there is demand:
(1...).publisher
.mapLazily { value in
print("Map: \(value)")
return value * 2
}
.subscribe(MySubscriber())
// Only transforms the values when they are demanded by the downstream subscriber every 3 seconds:
//
// Subscribed
// Map: 1
// Value: 2
// Map: 2
// Value: 4
// Map: 3
// Value: 6
// Map: 4
// Value: 8
My guess is that the particular overload of map defined for Publishers.Sequence is using some kind of shortcut to enhance performance. This breaks for infinite sequences, but even for finite sequences eagerly exhausting the sequence regardless of the downstream demand messes with my intuition. In my view, the following code:
(1...3).publisher
.map { value in
print("Map: \(value)")
return value * 2
}
.subscribe(MySubscriber())
ought to print:
Subscribed
Map: 1
Value: 2
Map: 2
Value: 4
Map: 3
Value: 6
Complete
but instead prints:
Map: 1
Map: 2
Map: 3
Subscribed
Value: 2
Value: 4
Value: 6
Complete
Here's a simpler test that doesn't involve any custom subscribers:
(1...).publisher
//.map { $0 }
.flatMap(maxPublishers: .max(1)) {
(i:Int) -> AnyPublisher<Int,Never> in
Just<Int>(i)
.delay(for: 3, scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
}
.sink { print($0) }
.store(in: &storage)
It works as expected, but then if you uncomment the .map you get nothing, because the .map operator is accumulating the infinite upstream values without publishing anything.
On the basis of your hypothesis that map is somehow optimizing for a preceding sequence publisher, I tried this workaround:
(1...).publisher.eraseToAnyPublisher()
.map { $0 }
// ...
And sure enough, it fixed the problem! By hiding the sequence publisher from the map operator, we prevent the optimization.

Can't find a way to implement a wait function in my Swift code

I can't find a way to implement a wait function, I'm using swiftforwindows and no examples online have been able to solve it so far. It's Swift 4.2
The class is basically an array that when a function is called each index on the array gets a constant value deducted. the tick function is what is being called. I'm new to Swift.
class resProj {
var list = [1,1,1,1]
var projReq = [100,200,300,50]
var completed = false
func tick(){
for count in 0..<projReq.count{
if projReq[count] <= list[count]{
projReq[count] = 0
}
else if projReq[count] > list[count]{
projReq[count] -= list[count]
}
}
print(projReq)
}
init(
mathsP mathsIn: Int,
scienceP sciecnceIn: Int,
enginerP enginerIn: Int,
businessP businessIn: Int) {
self.list [0] = mathsIn
self.list [1] = sciecnceIn
self.list [2] = enginerIn
self.list [3] = businessIn
}
}
var spaceElev = resProj(
mathsP: 10,
scienceP: 20,
enginerP: 30,
businessP: 5)
var x = false
while x == false{
//wait function here pls//
print("tick", terminator:"?")
let y = readLine()
if y == "y"{
spaceElev.tick()
}
else{
print("gotta put y")
}
var templist = spaceElev.projReq
var templistcount = 0
templistcount = templist.count
for loop in 0..<templistcount{
if templist[loop] == 0{
templistcount -= 1
}
}
if templistcount == 0 {
x = true
print("project completed")
}
}
}
Where it says //wait function here pls// I would like to make the program wait for 1 second.
There are a lot of way to do this but most common way is create a completion function. For example:
func doSth(_ someParameter: String, _ completion: ()->()) {
print(someParameter)
// After your code is finish call completion
completion()
}
And when you call (there is two way to call):
doSth("Done") {
print("You can be sure that this block will work after your func finish")
}
or you can simply create another func and send it as a parameter.
You can also use DispatchQueue:
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
// put your func here...
}
You can simple use the UNIX-Functin func sleep(_: UInt32) -> UInt32.
In your case use sleep(1) to wait one second.
You could use Grand Central Dispatch or perform.
GCD solution:
let delayInSeconds = 1
DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) {
print("tick", terminator:"?")
}
If you want to learn more about Grand Central Dispatch (GCD) I suggest you read through this:
Grand Central Dispatch - Wikipedia
Grand Central Dispatch Tutorial - Ray Wenderlich
Perform solution:
Create a function like this:
#objc func delayedFunc() {
//write the code here that you want to execute with a one second delay
}
Then call this where you want the delayed function to execute:
let delayInSeconds = 1
perform(#selector(delayedFunc), with: nil, afterDelay: delayInSeconds)
You can use the RunLoop class:
func wait(for interval: TimeInterval) {
RunLoop.current.run(until: Date() + interval)
}

Swift for iOS - 2 for loops run at the same time?

I have two objects where I need to update their UI at the same time. I have a for loop for one, and after that another for loop. Each iteration in the for loop I have a short delay so that for elements in the object I am making a UI change... one after the other - not seemingly all at once.
func update(value: Int){
var delay: Double = 0.05
// first loop
for i in 0...value {
delayWithSeconds(delay) {
//do something with object 1
}
delay = delay + 0.05
}
var delay2: Double = 0.05
// second loop
for i in 0...value {
delayWithSeconds(delay2) {
//do something with object 2
}
delay2 = delay2 + 0.05
}
}
// Utility
func delayWithSeconds(_ seconds: Double, completion: #escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
I have tried wrapping each for loop with DispatchQueue.main.async and it didn't make a difference. In short - I would like to run both for loops at the same time (or perceived as such). These are on the UI thread.
I tried this and it seemed to work out quite well. It does exactly what I want it to do (at least visually they seem to run at the same time).
let concurrentQueue = DispatchQueue(label: "net.ericd.hello", attributes: .concurrent)
concurrentQueue.async {
//my loop with delay here for object 1.
}
concurrentQueue.async {
//my separate loop with delay here for object 2.
}
We can use it when we want execute different arrays at the same time:
using this Generic Function
zip(_:_:)
Here i took 2 array:
var arrOfInt = ["1","2","3"]
var arrOfIntString = ["one","two","three"]
for (intNum, intString) in zip(arrOfInt, arrOfIntString) {
print("Int:\(intNum), String:\(intString)")
}

Skip an event from source observable if a new event from a given observable was received in a given time interval

I'm trying to write a method on UIView extension, which will observe long press on a given view. I know it can be done using UILongPressGestureRecognizer, but I really want to figure out the question and do it this way.
I tried to use takeUntil operator, but it completes an observable, but I need to skip the value and receive further events.
The question can be also transformed to: How to omit completed event and keep receiving further events?
func observeLongPress(with minimumPressDuration: Double = 1) ->
Observable<Void> {
let touchesBeganEvent = rx.methodInvoked(#selector(touchesBegan))
let touchesEndedEvents = [#selector(touchesEnded), #selector(touchesCancelled)]
.map(rx.methodInvoked)
let touchesEndedEvent = Observable.merge(touchesEndedEvents)
return touchesBeganEvent
.observeOn(MainScheduler.instance)
.delay(minimumPressDuration, scheduler: MainScheduler.instance)
.takeUntil(touchesEndedEvent)
.map { _ in }
}
This will work, but will complete the whole sequence (as it intended to do).
The answer if floating around (as it always do), but after a few hours I decided to ask. :)
Update
The floating answer just flew inside (~15 mins for doing so), but I'm still interested in answer, because maybe there's something that I'm missing here.
func observeLongPress(with minimumPressDuration: Double = 1) -> Observable<Void> {
let touchesBeganEvent = rx.methodInvoked(#selector(touchesBegan))
let touchesEndedEvents = [#selector(touchesEnded), #selector(touchesCancelled)]
.map(rx.methodInvoked)
let touchesEndedEvent = Observable.merge(touchesEndedEvents)
return touchesBeganEvent
.observeOn(MainScheduler.instance)
.flatMapLatest { _ -> Observable<Void> in
return Observable.just(())
.delay(minimumPressDuration, scheduler: MainScheduler.instance)
.takeUntil(touchesEndedEvent)
.void()
}
}
Your Updated code won't work. Even if you don't emit the completed event out of the function, it still got emitted from the takeUntil and therefore that operator won't emit any more values.
That said, this idea can be accomplished. Since you said you want to learn, I'll talk through my entire thought process while writing this.
First let's outline our inputs and outputs. For inputs we have two Observables, and a duration, and whenever we are dealing with duration we need a scheduler. For outputs we only have a single Observable.
So the function declaration looks like this:
func filterDuration(first: Observable<Void>, second: Observable<Void>, duration: TimeInterval, scheduler: SchedulerType) -> Observable<Void> {
// code goes here.
}
We are going to be comparing the time that the two observables fire so we have to track that:
let firstTime = first.map { scheduler.now }
let secondTime = second.map { scheduler.now }
And since we are comparing them, we have to combine them somehow. We could use merge, combineLatest, or zip...
combineLatest will fire whenever either Observable fires and will give us the latest values from both observables.
zip will mate, 1 for 1, events from both observables. This sounds intriguing, but would break down if one of the observables fires more often than the other so it seems a bit brittle.
merge will fire when either of them fire, so we would need to track which one fired somehow (probably with an enum.)
Let's use combineLatest:
Observable.combineLatest(firstTime, secondTime)
That will give us an Observable<(RxTime, RxTime)> so now we can map over our two times and compare them. The goal here is to return a Bool that is true if the second time is greater than the first time by more than duration.
.map { arg -> Bool in
let (first, second) = arg
let tickDuration = second.timeIntervalSince(first)
return duration <= tickDuration
}
Now the above will fire every time either of the two inputs fire, but we only care about the events that emit true. That calls for filter.
.filter { $0 } // since the wrapped value is a Bool, this will accomplish our goal.
Now our chain is emitting Bools which will always be true but we want a Void. How about we just throw away the value.
.map { _ in }
Putting it all together, we get:
func filterDuration(first: Observable<Void>, second: Observable<Void>, duration: TimeInterval, scheduler: SchedulerType) -> Observable<Void> {
let firstTime = first.map { scheduler.now }
let secondTime = second.map { scheduler.now }
return Observable.combineLatest(firstTime, secondTime)
.map { arg -> Bool in
let (first, second) = arg
let tickDuration = second.timeIntervalSince(first)
return duration <= tickDuration
}
.filter { $0 }
.map { _ in }
}
The above isolates our logic and is, not incidentally, easy to test with RxTests. Now we can wrap it up into a UIView (that would be hard to test.)
func observeLongPress(with minimumPressDuration: Double = 1) -> Observable<Void> {
let touchesBeganEvent = rx.methodInvoked(#selector(touchesBegan)).map { _ in }
let touchesEndedEvents = [#selector(touchesEnded), #selector(touchesCancelled)]
.map(rx.methodInvoked)
let touchesEndedEvent = Observable.merge(touchesEndedEvents).map { _ in }
return filterDuration(first: touchesBeganEvent, second: touchesEndedEvent, duration: minimumPressDuration, scheduler: MainScheduler.instance)
}
There you go. One custom operator.

Testing a Timer in Xcode with XCTest

I have a function that does not need to be called any more than every 10 secs. Every time I invoke the function, I reset the timer to 10 secs.
class MyClass {
var timer:Timer?
func resetTimer() {
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: false) {
(timer) -> Void in
self.performAction()
}
}
func performAction() {
// perform action, then
self.resetTimer()
}
}
I would like to test that calling performAction() manually resets the timer to 10 secs, but I can't seem to find any good way to do it. Stubbing resetTimer() feels like the test wouldn't really be telling me enough about the functionality. Am I missing something?
XCTest:
func testTimerResets() {
let myObject = MyClass()
myObject.resetTimer()
myObject.performAction()
// Test that my timer has been reset.
}
Thanks!
If you want to wait for the timer to fire, you'll still need to use expectations (or Xcode 9's new asynchronous testing API).
The question is what precisely you're trying to test. You presumably don't want to just test that the timer fired, but rather you want to test what the timer's handler is actually doing. (Presumably you have a timer in order to perform something meaningful, so that's what we should be testing.)
WWDC 2017 video Engineering for Testability offers a nice framework to be thinking about how to design code for unit tests , which need:
control over inputs;
visibility to outputs; and
no hidden state.
So, what are the inputs to your test? And, more importantly, what is the output. What assertions do you want to test for in your unit test?
The video also shows a few practical examples of how one might refactor code to achieve this structure through judicious use of:
protocols and parameterization; and
separating logic and effects.
It's hard to advise further without knowing what the timer is actually doing. Perhaps you can edit your question and clarify.
Good that you found a solution, but answering the question in title;
To test if timer actually works (i.e. runs and calls callback), we can do something like:
import XCTest
#testable import MyApp
class MyClassTest: XCTestCase {
func testStartTimer_shouldTriggerCallbackOnTime() throws {
let exp = expectation(description: "Wait for timer to complete")
// Dummy.
let instance: MyClass! = MyClass()
instance.delay = 2000; // Mili-sec equal 2 seconds.
instance.callback = { _ in
exp.fulfill();
}
// Actual test.
instance.startTimer();
// With pause till completed (sleeps 5 seconds maximum,
// else resumes as soon as "exp.fulfill()" is called).
if XCTWaiter.wait(for: [exp], timeout: 5.0) != .completed {
XCTFail("Timer didn't finish in time.")
}
}
}
When having a class like:
public class MyClass {
public var delay: Int = 0;
public var callback: ((timer: Timer) -> Void)?
public func startTimer() {
let myTimer = Timer(timeInterval: Double(self.delay) / 1000.0, repeats: false) {
[weak self] timer in
guard let that = self else {
return
}
that.callback?(timer)
}
RunLoop.main.add(myTimer, forMode: .common)
}
}
First, I would say I don't know how your object was working when you don't any member called refreshTimer.
class MyClass {
private var timer:Timer?
public var starting:Int = -1 // to keep track of starting time of execution
public var ending:Int = -1 // to keep track of ending time
init() {}
func invoke() {
// timer would be executed every 10s
timer = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(performAction), userInfo: nil, repeats: true)
starting = getSeconds()
print("time init:: \(starting) second")
}
#objc func performAction() {
print("performing action ... ")
/*
say that the starting time was 55s, after 10s, we would get 05 seconds, which is correct. However for testing purpose if we get a number from 1 to 9 we'll add 60s. This analogy works because ending depends on starting time
*/
ending = (1...9).contains(getSeconds()) ? getSeconds() + 60 : getSeconds()
print("time end:: \(ending) seconds")
resetTimer()
}
private func resetTimer() {
print("timer is been reseted")
timer?.invalidate()
invoke()
}
private func getSeconds()-> Int {
let seconds = Calendar.current.component(.second, from: Date())
return seconds
}
public func fullStop() {
print("Full Stop here")
timer?.invalidate()
}
}
Testing (explanation in the comments)
let testObj = MyClass()
// at init both starting && ending should be -1
XCTAssertEqual(testObj.starting, -1)
XCTAssertEqual(testObj.ending, -1)
testObj.invoke()
// after invoking, the first member to be changed is starting
let startTime = testObj.starting
XCTAssertNotEqual(startTime, -1)
/*
- at first run, ending is still -1
- let's for wait 10 seconds
- you should use async method, XCTWaiter and expectation here
- this is just to give you a perspective or way of structuring your solution
*/
DispatchQueue.main.asyncAfter(deadline: .now() + 10 ) {
let startTimeCopy = startTime
let endingTime = testObj.ending
XCTAssertNotEqual(endingTime, -1)
// take the difference between start and end
let diff = endingTime - startTime
print("diff \(diff)")
// no matter the time, diff should be 10
XCTAssertEqual(diff, 10)
testObj.fullStop()
}
this is not the best of way of doing it, however it gives you view or a flow on how you should achieve this :)
I ended up storing the original Timer's fireDate, then checking to see that after the action was performed the new fireDate was set to something later than the original fireDate.
func testTimerResets() {
let myObject = MyClass()
myObject.resetTimer()
let oldFireDate = myObject.timer!.fireDate
myObject.performAction()
// If timer did not reset, these will be equal
XCTAssertGreaterThan(myObject.timer!.fireDate, oldFireDate)
}