NSTimer 应该从通知调用的方法内部触发
Posted
技术标签:
【中文标题】NSTimer 应该从通知调用的方法内部触发【英文标题】:NSTimer supposed to be fired from inside a method called by a notification 【发布时间】:2012-06-08 22:40:25 【问题描述】:在我的 ios 应用程序中,我已将 AppDelegate 注册为 CoreData 更改的通知侦听器。使用这段代码:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChangesFromContextDidSaveNotification:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:[self persistentStoreCoordinator]];
并且每次有更新时都会正确调用 mergeChangesFromContextDidSaveNotification 方法。
但是在这个方法中我试图调用一个 NSTimer 来做另一个操作:
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification
NSTimer *t =[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:@selector(mergeCoreDataFromCloud:)
userInfo:nil
repeats:NO];
关键是永远不会调用应由计时器触发的mergeCoreDataFromCloud:。这是签名:
-(void)mergeCoreDataFromCloud:(NSTimer*)timer
// never called...
请注意,我处于开发的早期阶段,代码并不完美,我只想知道为什么计时器没有启动。 我想它与线程有关,但我没有猜测......
谢谢
【问题讨论】:
【参考方案1】:计时器依赖于运行循环在它被调度的模式下运行。
在 Cocoa 应用程序中,主线程自动运行其运行循环。但是,不能依赖其他线程自动运行其运行循环。
因此,通常您希望在主线程上安排计时器。您还可以将它们安排在您创建和控制的线程上,从而以适当的模式运行其运行循环。
您的问题中没有足够的信息来了解调用此代码的线程。
【讨论】:
【参考方案2】:您可能对线程问题是正确的——就是这样,然后我认为您必须使用计划外的计时器并将其手动添加到运行循环中。试试这个,看看它是否有效:
NSTimer *t = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(mergeCoreDataFromCloud:) userInfo:nil repeats:NO];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:t forMode:NSDefaultRunLoopMode];
【讨论】:
这与+scheduledTimerWithTimeInterval:...
实现的效果完全相同。
@KenThomases,是的,我想知道这一点。文档说在辅助线程上必须自己运行运行循环,所以我认为这值得一试。以上是关于NSTimer 应该从通知调用的方法内部触发的主要内容,如果未能解决你的问题,请参考以下文章
如何从 ViewController 或其他地方调用或触发 AppDelegate 中的通知功能?