寻找MacOS Threaded Networking示例代码

时间:2020-03-06 14:58:40  来源:igfitidea点击:

我的代码需要在单独的NSThread中运行所有网络例程。
我有一个库,我通过一个回调例程进行通信:

my thread code
    library
        my callback (networking)
    library
my thread code

我的回调例程必须将一些数据发布到HTTP服务器(NSURLConnection),等待答案(启动NSRunLoop?),然后返回库。
然后,库将处理数据。
库返回我的线程后,我可以将通知发布到处理图形和用户输入的主线程。

是否有任何示例代码涵盖如何在NSThread中使用NSURLConnection?

解决方案

要回答小问题"启动NSRunLoop?":

我不确定我是否理解,但这听起来像是我们在说上面的伪代码都是在辅助线程(即不是主事件处理线程)上执行的。在这种情况下,创建NSRunLoop可能没有任何意义,因为在等待HTTP服务器响应时我们无法做任何有用的工作。只是让线程阻塞。

如果需要阻塞直到完成工作并且已经在一个单独的线程上,则可以使用+ [NSURLConnection sendSynchronousRequest:returningResponse:error:]。不过这有点钝,因此,如果我们需要更多控制权,则必须切换到异步的" NSURLRequest",并在当前的" NSRunLoop"中安排委托方法(即回调)。在那种情况下,一种方法可能是让委托标志完成后,允许运行循环处理事件,直到设置标志或者超过超时为止。

NSURLConnection可以通过其异步委托方法在后台线程(例如NSThread或者NSOperation)中同步使用。但是,它确实需要了解NSRunLoop的工作方式。

这里有一个带有示例代码和说明的博客文章:
http://stackq.com/blog/?p=56

该示例代码下载了一个图像,但是我已经使用该概念对REST API进行了复杂的POST调用。

-开尔文

我们使用线程有任何特殊原因吗?除非我们打开大量连接,否则主线程上的NSRunLoop应该足够好。如果我们需要进行阻塞工作以响应,请创建线程。

开尔文(Kelvin)的链接已死,下面的代码可以满足要求(只能在[NSThread detachNewThreadSelector:toTarget:WithObject:]调用的方法中运行)。请注意,连接基本上从进入运行循环开始就开始工作,并且" terminateRunLoop"的含义是BOOL在启动时设置为NO,并在连接完成加载或者出现错误时设置为YES。

为什么要执行此操作而不是阻止同步请求?原因之一是我们可能希望能够正确取消长时间运行的连接,即使我们没有很多连接也是如此。我也看到,如果我们在主运行循环中开始有大量异步请求,则UI会变得有些挂断。

NSURLConnection *connection = [[NSURLConnection connectionWithRequest:request delegate:self] retain];
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
while(!terminateRunLoop) 
{
    if ( ![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                                   beforeDate:[NSDate distantFuture]]) 
        {  break; }

        [pool drain];
    }
    [pool release];
}