- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在我的应用程序中使用官方 Ricoh Theta iOS SDK (Link) 连接到 360° Ricoh Theta 相机。 SDK 使用多个 HTTP 请求来触发图像的捕获并从相机下载图像。
SDK 在内部使用信号量来同步请求,但自从升级到 iOS 10 后,由于某种原因,这似乎不再起作用。根据开发者论坛的说法,这个问题是已知的,但理光显然并不在意。
我将其缩小到 SDK 中的特定部分,SDK 通过 RunLoop 每 0.5 秒发送一次请求,循环检查图像是否可用。
这发生在这个函数中:
/**
* Start status monitoring
* @param command ID of command to be monitored
* @return Status indicating completion or error
*/
- (NSString*)run:(NSString*)command
{
// Create and keep HTTP session
NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session= [NSURLSession sessionWithConfiguration:config];
_commandId = command;
// Semaphore for synchronization (cannot be entered until signal is called)
_semaphore = dispatch_semaphore_create(0);
// Create and start timer
NSTimer *timer = [NSTimer timerWithTimeInterval:0.5f
target:self
selector:@selector(getState:)
userInfo:nil
repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSRunLoopCommonModes];
[runLoop run];
// Wait until signal is called
dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"HERE");
return _state;
}
NSLog(@"HERE");
即使在 getState 方法 (
dispatch_semaphore_signal(_semaphore);
) 中触发了 Semaphore,也永远不会调用。通过单步调试器中的行,我可以肯定地知道这一点。
/**
* Delegate called during each set period of time
* @param timer Timer
*/
- (void)getState:(NSTimer*)timer {
// Create JSON data
NSDictionary *body = @{@"id": _commandId};
// Set the request-body.
[_request setHTTPBody:[NSJSONSerialization dataWithJSONObject:body options:0 error:nil]];
// Send the url-request.
NSURLSessionDataTask* task =
[_session dataTaskWithRequest:_request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSArray* array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
_state = [array valueForKey:@"state"];
_fileUri = [array valueForKeyPath:@"results.fileUri"];
NSLog(@"result: %@", _state);
} else {
_state = @"error";
NSLog(@"GetStorageInfo: received data is invalid.");
}
if (![_state isEqualToString:@"inProgress"]) {
[timer invalidate];
dispatch_semaphore_signal(_semaphore);
// Stop timer
[timer invalidate];
}
}];
[task resume]; }
dispatch_semaphore_wait
的新线程。 .
最佳答案
这与信号量无关。
documentation for -[NSRunLoop run]
说:
Puts the receiver into a permanent loop, during which time it processes data from all attached input sources. […]
If no input sources or timers are attached to the run loop, this method exits immediately; otherwise, it runs the receiver in the
NSDefaultRunLoopMode
by repeatedly invokingrunMode:beforeDate:
. In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers.Manually removing all known input sources and timers from the run loop is not a guarantee that the run loop will exit. macOS can install and remove additional input sources as needed to process requests targeted at the receiver’s thread. Those sources could therefore prevent the run loop from exiting.
If you want the run loop to terminate, you shouldn't use this method. Instead, use one of the other run methods and also check other arbitrary conditions of your own, in a loop. A simple example would be:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);where
shouldKeepRunning
is set toNO
somewhere else in the program.
-run:
中的任何代码
[runLoop run]
之后的方法call 将永远被执行。
-run
返回。方法。这种希望是不合理的。它在某些情况下在某些版本的操作系统上工作的事实是不幸的巧合。 (不幸的是,如果它没有奏效,他们会意识到自己的错误并找到不同的方法。)
shouldKeepRunning
时才有效。为假。这是因为,据记录,
-runMode:beforeDate:
计时器触发时不一定会返回。因此,您需要使用输入源来触发退出。
NSPort
“戳”运行循环。您可以使用
-performSelector:onThread:withObject:waitUntilDone:
,针对正在运行循环的线程。你不能做跨线程
NSRunLoop
访问,但您可以下拉到
CFRunLoop
API,是线程安全的,通过
-getCFRunLoop
.然后,您可以使用
CFRunLoopPerformBlock()
和
CFRunLoopWakeUp()
运行一个设置
shouldKeepRunning
的 block 为假。
-run:
方法应该
CFRetain()
CFRunLoop
然后是调用
CFRunLoopWakeUp()
的代码应该
CFRelease()
它,只是为了确保它可以根据需要生存。否则,在原始线程和
CFRunLoopWakeUp()
内的任何最终工作之间存在潜在的竞争条件。 .
NSTimer
来替换其中的大部分内容。然后停止使用
NSRunLoop
东西。这取决于是否
-getState:
确实需要在与
-run:
相同的线程上运行.使用当前代码,它确实在同一个线程上运行。使用调度计时器源,它不会。仅使用部分代码很难说,但在我看来,使用调度计时器源应该没有任何问题。
关于ios - 自从升级到 iOS10 后,带有 NSRunLoop 的信号量无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649088/
崩溃发生在以下代码中: void CocoaCommRequest::launchSync() { launchAsync(); while (![_delegate finished
我的 iPhone 应用程序中有几个选项卡,需要几秒钟的时间才能加载(从本地 sqlite 数据库中提取大量数据)。当用户触摸选项卡时,应用程序似乎什么也没做。我试图放置一个显示旋转器的窗口,但是由于
我开始将 RunLoop 理解为类似于 Java 中的事件队列。我现在尝试做的 Wgat,只是为了更好地理解,是在运行自己的 RunLoop 的应用程序中创建一个后台线程。我在示例 ViewContr
我制作了一个带有计时器的 RunLoop,该计时器更新显示倒计时的标签。我需要 RunLoop 在倒计时达到零时停止,对于计时器正常完成的情况,我可以使用 runUntilDate,日期为当前日期 +
我在线程中有一个连接,因此我将其添加到运行循环中以获取所有数据: [[NSRunLoop currentRunLoop] run]; [connection scheduleInRunLoop
我有一个每 5 分钟调用一次的后台方法。 该方法使用NSURLConnection将数据发送到 Web 服务。 在那种方法中,我有这个代码: ... conn = [[NSURLConnection
我对 NSRunLoop 的实现很感兴趣,它可以在不占用大量 CPU 的情况下让线程空闲/休眠。这在 Objective-c 中是如何实现的?消耗高 CPU 的简单解决方案是 while(YES) {
在我的应用程序中,我需要对 restful web api 进行 https 调用并在返回时处理结果。同时服务调用的数量从来都不是固定的,因此相应地编写了相关代码。从服务获取的数据临时存储在应用程序内
我在自定义单元格上使用 NSTimer 运行 NSRunLoop 以持续更新“有效至”UILabel。它工作正常,直到我关闭 tableView,NSRunLoop 继续倒计时。我使用 dealloc
我不太清楚 NSRunLoop 是否线程安全。所以我需要澄清一下它是否线程安全,为什么? 任何帮助都是可观的。 最佳答案 在 NSRunLoop 的开头有一个警告 official reference
谁能解释一下什么是NSRunLoop?据我所知,NSRunLoop 是与 NSThread 相关的东西,对吗?所以假设我创建了一个像 这样的线程 NSThread* th=[[NSThread all
我刚刚在我的 ViewController 中使用 NSRunLoop 和 NSTimer 创建了一个带计时器的后台任务: - (void)runBackgroundTask: (int) time{
我读了很多关于 NSRunLoop 的帖子,比如 this , this , this .但无法弄清楚 NSRunLoop 实际上做了什么 我平时看到的是工作线程 wthread = [[NSThre
谁能解释什么是NSRunLoop?所以据我所知 NSRunLoop 是与 NSThread 相关的东西,对吗?所以假设我创建了一个像 这样的线程 NSThread* th=[[NSThread all
我试图在守护进程结束时或者有人退出该进程时释放在守护进程中分配的资源。 可以说, int main(int argc, const char * argv[]) { Controller *c
在 Cocoa 应用程序中,运行如下代码: NSDate* date = [NSDate dateWithTimeIntervalSinceNow:30.0]; while (date.timeInt
我买了《Big Nerd Ranch Guide for Objective-C》,但有一些关于 NSRunLoop 的内容我不明白。 这是书中的一段代码: NSTimer *timer = [NST
假设我有 2 个线程,一个是主线程,另一个是辅助线程。主线程使用最多,但有时(很少)我希望辅助线程根据主线程的调用执行一些工作。大多数时候辅助线程应该休眠。现在,经过一番搜索,我明白做到这一点的方法是
我正在编写一个应用程序,它必须与通过 USB 连接的设备进行通信。该应用程序按固定时间轮流从设备发送和接收数据。所有 Rx/Tx 都发生在单独的线程中,否则 UI 将被阻塞。基本结构基本上是这样的。
我正在使用 NSUrlConnection 来发出 http 请求。我想避免使用事件驱动代码,所以我通过以下方式使用 NSRunloop: NSURLRequest *request = [[NSUR
我是一名优秀的程序员,十分优秀!