我正在尝试通过iOS上的GCD将一些代码发送到主队列,但即使是最简单的测试也总是失败。最后归结为:
static const int TICK_INTERVAL = 1;
#pragma UIApplicationDelegate implementation
- (void) doTick
{
if (![NSThread isMainThread])
{
NSLog(@"Trying to dispatch . . .");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"test . . .");
});
}
}
- (void) startUpdate
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
timer_ = [NSTimer
scheduledTimerWithTimeInterval:TICK_INTERVAL
target:self
selector:@selector(backgroundUpdate)
userInfo:nil
repeats:NO
];
[[NSRunLoop currentRunLoop]
addTimer:timer_
forMode:NSRunLoopCommonModes
];
[[NSRunLoop currentRunLoop] run];
});
UIBackgroundTaskIdentifier back =
[[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
[self doTick];
[[UIApplication sharedApplication]
endBackgroundTask:back
];
}];
}
-(void)backgroundUpdate
{
[self doTick];
UIBackgroundTaskIdentifier back =
[[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
[self doTick];
[[UIApplication sharedApplication]
endBackgroundTask:back
];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
timer_ = [NSTimer
scheduledTimerWithTimeInterval:TICK_INTERVAL
target:self
selector:@selector(backgroundUpdate)
userInfo:nil
repeats:NO
];
[[NSRunLoop currentRunLoop]
addTimer:timer_
forMode:NSRunLoopCommonModes
];
[[NSRunLoop currentRunLoop] run];
});
}
- (id) init
{
self = [super init];
[self startUpdate];
return self;
}
那是我的AppDelegate
。
我希望NSLog在主线程中执行以记录上面的测试文本,但没有任何反应。 dispatch_sync
代码只是永远等待,我放在块中的断点永远不会到达。
我确保代码不在主线程中执行。在使用dispatch_sync
进行测试之前,我在我的应用中尝试了dispatch_async
,结果当然基本相同:没有任何反应(没有阻止)。
有趣的是,它似乎不适用于主队列,其他队列(当前队列,全局队列)似乎工作正常。
我在我的应用中使用Phonegap(Cordova),如果这有任何意义。
任何想法?
非常感谢!
答案 0 :(得分:4)
您永远不应该dispatch_sync
从队列中执行的任务到同一个队列。这可以保证在主队列之类的任何串行队列上死锁,并且在并发队列上是个坏主意。有关详细信息,请参阅Apple's Concurrency Programming Guide。由于应用程序委托的init方法在主线程上运行,因此dispatch_sync
到主队列会导致死锁。
dispatch_async
到主队列就会起作用。当然,您的NSLog(@"test . . .")
可能会在完成申请代表的init方法之后执行。