Merge pull request #2036 from NativeScript/feature/timer-fix

Fix: Timer somtimes crashing in IOS
This commit is contained in:
Alexander Vakrilov
2016-04-26 12:48:06 +03:00
2 changed files with 64 additions and 10 deletions

View File

@ -118,4 +118,54 @@ export function test_setInterval_callbackShouldBeCleared() {
TKUnit.waitUntilReady(() => false, 0.5); TKUnit.waitUntilReady(() => false, 0.5);
TKUnit.assert(counter === 1, "Callback should be raised only once!"); TKUnit.assert(counter === 1, "Callback should be raised only once!");
}; };
export function test_clearTimeout_multipleTimes_afterTick() {
let completed = false;
let id = timer.setTimeout(() => {
completed = true;
});
TKUnit.waitUntilReady(() => completed, 0.5);
TKUnit.assert(completed, "Callback should be called");
timer.clearTimeout(id);
timer.clearTimeout(id);
}
export function test_clearTimeout_immediatelyAfterCreate() {
let completed = false;
let id = timer.setTimeout(() => {
completed = true;
});
timer.clearTimeout(id);
TKUnit.waitUntilReady(() => false, 0.02);
TKUnit.assert(!completed, "Callback should not be called");
}
export function test_clearInterval_immediatelyAfterCreate() {
let completed = false;
let id = timer.setInterval(() => {
completed = true;
});
timer.clearInterval(id);
TKUnit.waitUntilReady(() => false, 0.02);
TKUnit.assert(!completed, "Callback should not be called");
}
export function test_clearTimeout_insideCallback() {
let completed = false;
let id = timer.setTimeout(() => {
completed = true;
timer.clearTimeout(id);
});
TKUnit.waitUntilReady(() => completed, 0.5);
TKUnit.assert(completed, "Callback should be called");
}

View File

@ -10,33 +10,37 @@ interface KeyValuePair<K, V> {
} }
class TimerTargetImpl extends NSObject { class TimerTargetImpl extends NSObject {
private _callback: Function; private callback: Function;
public canceled = false; private disposed: boolean;
private id: number private id: number
private shouldRepeat: boolean private shouldRepeat: boolean
public static initWithCallback(callback: Function, id: number, shouldRepeat: boolean): TimerTargetImpl { public static initWithCallback(callback: Function, id: number, shouldRepeat: boolean): TimerTargetImpl {
let handler = <TimerTargetImpl>TimerTargetImpl.new(); let handler = <TimerTargetImpl>TimerTargetImpl.new();
handler._callback = callback; handler.callback = callback;
handler.id = id; handler.id = id;
handler.shouldRepeat = shouldRepeat; handler.shouldRepeat = shouldRepeat;
return handler; return handler;
} }
public tick(timer): void { public tick(timer): void {
if (!this.canceled) { if (!this.disposed) {
this._callback(); this.callback();
} }
if (this.canceled || !this.shouldRepeat) { if (!this.shouldRepeat) {
this.unregister(); this.unregister();
} }
} }
public unregister() { public unregister() {
let timer = timeoutCallbacks.get(this.id).k; if (!this.disposed) {
timer.invalidate(); this.disposed = true;
timeoutCallbacks.delete(this.id);
let timer = timeoutCallbacks.get(this.id).k;
timer.invalidate();
timeoutCallbacks.delete(this.id);
}
} }
public static ObjCExposedMethods = { public static ObjCExposedMethods = {