Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa touch 使用NSNetService实现的同步Bonjour解析(为什么从runloop返回控制需要这么长时间?)_Cocoa Touch_Bonjour_Synchronous_Nsrunloop_Nsnetservice - Fatal编程技术网

Cocoa touch 使用NSNetService实现的同步Bonjour解析(为什么从runloop返回控制需要这么长时间?)

Cocoa touch 使用NSNetService实现的同步Bonjour解析(为什么从runloop返回控制需要这么长时间?),cocoa-touch,bonjour,synchronous,nsrunloop,nsnetservice,Cocoa Touch,Bonjour,Synchronous,Nsrunloop,Nsnetservice,我正在尝试同步执行服务名称的“你好”解析,因此我正在尝试找出如何正确等待NSNetService的netServiceDidResolveAddress()调用 我的代码如下所示: service = [[NSNetService alloc] initWithDomain:@"local." type:@"_myservice._tcp" name:[self name]]; [service retain]; [service setDelegate:self]; waitingOnReso

我正在尝试同步执行服务名称的“你好”解析,因此我正在尝试找出如何正确等待NSNetService的netServiceDidResolveAddress()调用

我的代码如下所示:

service = [[NSNetService alloc] initWithDomain:@"local." type:@"_myservice._tcp" name:[self name]];
[service retain];
[service setDelegate:self];
waitingOnResolution = true;
[service resolveWithTimeout:5.0];

for (int i=0;i<5;i++) {
    DebugLog(@"resolve: resolve iteraton %u\n", i);
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; // run loop for one second
    DebugLog(@"resolve: resolve iteraton %u (after run loop)\n", i);
    if (!waitingOnResolution) break;   
}

// continue processing...
只要我的代码在resolve事件出现后继续运行一秒钟左右,我就会很高兴

实际发生的是,解析过程非常快,我看到netServiceDidResolveAddress()中的代码已完成,但在控件从runUntilDate返回之前,始终存在5-6秒的不希望出现的等待,我看到了“…(运行后循环)调试语句

我在几个留言板上四处查看,发现了类似的问题,但他们的解决方案(比如使用CFRunLoopStop)似乎没有任何效果

以下是我收到的日志记录示例:

2011-07-11 09:38:07.267 MyProgram[1822:707] resolve: resolve iteraton 0
2011-07-11 09:38:07.299 MyProgram[1822:707] netService: netServiceDidResolveAddress function ended

[5+ second delay]

2011-07-11 09:38:12.907 MyProgram[1822:707] resolve: resolve iteraton 0 (after run loop)

如果有人能告诉我使用NSNetService解析获得同步结果的不同方法,或者重构与runloop相关的代码以避免这种情况(似乎是OS创建的)5-6秒的延迟,我会很感激的。

你真的不应该这样做。网络解析是异步的,有一个很好的理由:执行解析可能需要很长时间,而且在大多数情况下,你不想在这段时间内阻塞线程。如果你在主线程上执行解析,你真的不想 希望同步执行。在Mac OS X上,长时间运行的阻止主线程的操作将导致旋转的海滩球。在iOS上,看门狗可能会完全杀死你的应用程序

API是异步的,以鼓励您正确地使用它。不要试图反对它


既然您没有解释为什么要尝试同步执行此操作,我就无能为力了,但请记住Cocoa是事件驱动的。将同步步骤分解为状态,让Cocoa在每个阶段的回调驱动您的状态机。它看起来不像一个逐行的过程函数,但它将保持您的状态用户界面响应快,避免难看的解决方法。

您真的不应该这样做。网络解析是异步的,原因很好:执行解析可能需要很长时间,而且在大多数情况下,您不想在持续时间内阻塞线程。如果您在主线程上执行解析,则确实不需要>希望同步执行。在Mac OS X上,长时间运行的阻止主线程的操作将导致旋转的海滩球。在iOS上,看门狗可能会完全杀死你的应用程序

API是异步的,以鼓励您正确地使用它。不要试图反对它


既然您没有解释为什么要尝试同步执行此操作,我就无能为力了,但请记住Cocoa是事件驱动的。将同步步骤分解为状态,让Cocoa在每个阶段的回调驱动您的状态机。它看起来不像一个逐行的过程函数,但它将保持您的状态用户界面响应迅速,避免出现难看的解决方法。

只需删除
CFRunLoopStop
,它就可以正常工作。停止
NSRunLoop
将停止此
NSThread
上的任何其他事件。我也这样做了(没有停止RunLoop)用于同步解析某些
NSNetServices
,它工作正常。

只需删除
CFRunLoopStop
,它应该工作正常。停止
NSRunLoop
将停止此
NSThread
上的任何其他事件。我做了同样的操作(没有停止RunLoop)用于同步解析某些
NSNetServices
,效果很好。

Steve,谢谢你的回答。所有事件驱动逻辑的问题是,我在几个地方调用解析,每个地方都可以从系统事件(如按下按钮)的几个功能级别调用。因此,为了确保我“返回”到流中的同一位置,我需要某种方法来设置函数指针,但即使这样,确切的堆栈也不会相同。当然,我可以重构大部分程序以适应事件模型,但因为我设置了硬限制(秒)关于解决方案需要多长时间,我似乎可以在这里强制同步行为。你正在为自己设置一些讨厌的错误和困难的调试。你应该重构。不要与框架抗争;最终你将比遵循Cocoa的指导方针花费更多的时间和精力。不要尝试保存函数指针和重新创建吃堆栈帧。构建一个状态机,并在事情发生时遍历您的状态。Steve,谢谢你的回答。所有事件驱动逻辑的问题是,有几个地方我可以调用解析,每个地方都可以从一个系统事件中调用几个功能级别(如按下按钮)。因此,为了确保我“返回”到流中的同一位置,我需要某种方法来设置函数指针,但即使这样,确切的堆栈也不会相同。当然,我可以重构大部分程序以适应事件模型,但因为我设置了硬限制(秒)关于解决方案需要多长时间,我似乎可以在这里强制同步行为。你正在为自己设置一些讨厌的错误和困难的调试。你应该重构。不要与框架抗争;最终你将比遵循Cocoa的指导方针花费更多的时间和精力。不要尝试保存函数指针和重新创建吃堆栈框架。建立一个状态机,随着事情的发生在你的状态中移动。
2011-07-11 09:38:07.267 MyProgram[1822:707] resolve: resolve iteraton 0
2011-07-11 09:38:07.299 MyProgram[1822:707] netService: netServiceDidResolveAddress function ended

[5+ second delay]

2011-07-11 09:38:12.907 MyProgram[1822:707] resolve: resolve iteraton 0 (after run loop)