对操作进行计时并在需要很长时间才能告诉用户等待时触发委托

发布于 2024-12-09 13:13:32 字数 769 浏览 0 评论 0原文

我创建了一个 NSOperation 来在后台完成一些繁重的工作,但我需要在比平时花费更长的时间时通知用户。

- (void)timerFireMethod {
    if (_TheOperationStillWorking) {
        // fire a delegate on the main thread to update the user interface...
    }
}
- (void)doSomeHeavyWork {
    _TheOperationStillWorking = YES;
    NSTimer * timer = [NSTimer timerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

    // Some code that BLOCKS the current NSOperation that executes this function...
    _TheOperationStillWorking = NO;
}

我已经尝试过 NSTimer 类,但由于代码阻塞了当前线程,因为它从互联网同步读取一些大数据,所以 NSTimer 不会触发。 有没有更好的方法来实现这一点,如果 NSTimer 是如何使用它的最佳方法?

任何帮助将不胜感激,并提前致谢。

I've created an NSOperation to do some heavy work in background but I need to notify the user when it takes longer time than usual.

- (void)timerFireMethod {
    if (_TheOperationStillWorking) {
        // fire a delegate on the main thread to update the user interface...
    }
}
- (void)doSomeHeavyWork {
    _TheOperationStillWorking = YES;
    NSTimer * timer = [NSTimer timerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

    // Some code that BLOCKS the current NSOperation that executes this function...
    _TheOperationStillWorking = NO;
}

I've tried the NSTimer class but as the code blocks the current thread, because it reads synchronously some large data from the internet, the NSTimer won't fire.
Is there any better way to accomplish that and if NSTimer is the best way how to use it?

Any help would be greatly appreciated, and thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落墨 2024-12-16 13:13:32

您可以从主线程安排计时器:

- (void)doSomeHeavyWork {
    _TheOperationStillWorking = YES;
    [self performSelectorOnMainThread:@selector(scheduleTimer) withObject:nil waitUntilDone:NO];

    // Some code that BLOCKS the current NSOperation that executes this function...

    _TheOperationStillWorking = NO;
}

- (void)scheduleTimer {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
}

- (void)timerFireMethod {
    OSMemoryBarrier(); // make sure private var is up to date
    if (_TheOperationStillWorking) {
        // updates here will happen on the main thread...
    }
}

有关为什么需要 OSMemoryBarrier() 来保护变量的信息,请参阅 此页面

You can schedule the timer from the main thread:

- (void)doSomeHeavyWork {
    _TheOperationStillWorking = YES;
    [self performSelectorOnMainThread:@selector(scheduleTimer) withObject:nil waitUntilDone:NO];

    // Some code that BLOCKS the current NSOperation that executes this function...

    _TheOperationStillWorking = NO;
}

- (void)scheduleTimer {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
}

- (void)timerFireMethod {
    OSMemoryBarrier(); // make sure private var is up to date
    if (_TheOperationStillWorking) {
        // updates here will happen on the main thread...
    }
}

For info on why you need OSMemoryBarrier() to protect your variable, see this page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文