Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/37.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
Iphone 用于异步web服务调用的NSURLConnection NSURLRequest代理_Iphone_Asynchronous_Uiviewcontroller_Nsurlconnection_Nsurlrequest - Fatal编程技术网

Iphone 用于异步web服务调用的NSURLConnection NSURLRequest代理

Iphone 用于异步web服务调用的NSURLConnection NSURLRequest代理,iphone,asynchronous,uiviewcontroller,nsurlconnection,nsurlrequest,Iphone,Asynchronous,Uiviewcontroller,Nsurlconnection,Nsurlrequest,我有多个视图,它们生成相同的NSURLRequest/NSURLConnection request。理想情况下,为了获得一些代码重用,我希望有某种“代理”,它完成创建/执行(异步)请求/连接、设置所有委托方法等所有底层工作,因此我不必在每个视图中复制所有NSURLConnection委托方法处理程序。首先,这种设计方法是否合理?第二,我该怎么做这样的事情呢 作为一点背景信息,我尝试了这一点,并使其“工作”,然而,它似乎没有异步执行。我创建了一个Proxy.h/m文件,其中包含用于不同web服务

我有多个视图,它们生成相同的
NSURLRequest/NSURLConnection request
。理想情况下,为了获得一些代码重用,我希望有某种“代理”,它完成创建/执行(异步)请求/连接、设置所有委托方法等所有底层工作,因此我不必在每个视图中复制所有
NSURLConnection
委托方法处理程序。首先,这种设计方法是否合理?第二,我该怎么做这样的事情呢

作为一点背景信息,我尝试了这一点,并使其“工作”,然而,它似乎没有异步执行。我创建了一个Proxy.h/m文件,其中包含用于不同web服务调用的实例方法(还包含
NSURLConnection
delegate方法):


我可以提供更多的代码,但剩余的代码可以假设。在调用之前,我“启动”了一个
UIActivityIndicatorView
spinner。但旋转器从不旋转。如果我只是将NSURLConnection委托方法直接放在视图控制器中,则微调器会旋转。因此,它使我认为我的实现不是异步执行的。有什么想法吗?

您的方法是合理的,但是,我不知道您为什么要创建自己的协议。这是没有必要的。实现这一点所需的一切都在苹果的电脑中。如果从实例化NSURLConnection的页面获取代码,并将该连接设置为ivar,而不是将其创建为局部变量,则可以比较每个回调方法中的连接对象,并做出相应的响应。例如,从文档中获取此代码,并将连接对象更改为ivar:

// create the request
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]
                        cachePolicy:NSURLRequestUseProtocolCachePolicy
                    timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
    // Create the NSMutableData that will hold
    // the received data
    // receivedData is declared as a method instance elsewhere
    receivedData=[[NSMutableData data] retain];
} else {
    // inform the user that the download could not be made
}
连接的变量是我们的ivar。然后你可以这样检查它:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (connection == theConnection)
    {
        // do something with the data object.
        [connectionSpecificDataObject appendData:data];
    }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (connection == theConnection)
    {
        if (delegate && [delegate respondsToSelector:successSelector])
            [delegate performSelector:successSelector 
                           withObject:connectionSpecificDataObject];
    }
    [connection release];
}
Proxy *p = [[Proxy alloc] init];
[p searchForSomethingAsync:searchText 
                  delegate:self 
           successSelector:@selector(didFinishWithData:) 
              failSelector:@selector(didFailWithError:)];
- (void)didFinishWithData:(NSData*)data;
{
    // Do something with data
}

- (void)didFailWithError:(NSError*)error
{
    // Do something with error
}
您当然可以按照您的建议创建自己的协议来实现它,然后调用符合您的协议的委托,但是您最好使用您可以检查的成功和失败选择器来实例化您的对象。大概是这样的:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (connection == theConnection)
    {
        // do something with the data object.
        [connectionSpecificDataObject appendData:data];
    }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (connection == theConnection)
    {
        if (delegate && [delegate respondsToSelector:successSelector])
            [delegate performSelector:successSelector 
                           withObject:connectionSpecificDataObject];
    }
    [connection release];
}
Proxy *p = [[Proxy alloc] init];
[p searchForSomethingAsync:searchText 
                  delegate:self 
           successSelector:@selector(didFinishWithData:) 
              failSelector:@selector(didFailWithError:)];
- (void)didFinishWithData:(NSData*)data;
{
    // Do something with data
}

- (void)didFailWithError:(NSError*)error
{
    // Do something with error
}
其中dataDidDownloadSelector是一个SEL实例变量,您在创建包含所有这些代码的下载委托时设置了该变量——您的代理对象。大概是这样的:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (connection == theConnection)
    {
        // do something with the data object.
        [connectionSpecificDataObject appendData:data];
    }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (connection == theConnection)
    {
        if (delegate && [delegate respondsToSelector:successSelector])
            [delegate performSelector:successSelector 
                           withObject:connectionSpecificDataObject];
    }
    [connection release];
}
Proxy *p = [[Proxy alloc] init];
[p searchForSomethingAsync:searchText 
                  delegate:self 
           successSelector:@selector(didFinishWithData:) 
              failSelector:@selector(didFailWithError:)];
- (void)didFinishWithData:(NSData*)data;
{
    // Do something with data
}

- (void)didFailWithError:(NSError*)error
{
    // Do something with error
}
实现选择器,如下所示:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (connection == theConnection)
    {
        // do something with the data object.
        [connectionSpecificDataObject appendData:data];
    }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (connection == theConnection)
    {
        if (delegate && [delegate respondsToSelector:successSelector])
            [delegate performSelector:successSelector 
                           withObject:connectionSpecificDataObject];
    }
    [connection release];
}
Proxy *p = [[Proxy alloc] init];
[p searchForSomethingAsync:searchText 
                  delegate:self 
           successSelector:@selector(didFinishWithData:) 
              failSelector:@selector(didFailWithError:)];
- (void)didFinishWithData:(NSData*)data;
{
    // Do something with data
}

- (void)didFailWithError:(NSError*)error
{
    // Do something with error
}
这已成为一个比我预期的更长的答案。如果没有意义,请告诉我,我可以尝试澄清


最好的祝愿,

您的代码保持原样,我认为这不会起任何作用-您在初始化后立即释放代理,因此它甚至不会运行


我喜欢使用的一种方法是同步NSURLConnection调用,它位于NSOperation内部,然后由NSOperationQueue管理。我将队列中的对象设置为单例,因此我只需从任何位置访问实例,并在需要启动新连接时告诉它。

Ah-非常好!我明白你的意思了——你的解决方案将不再需要协议。更直截了当!谢谢你!不过,我想,我已经开始对Kendal建议的解决方案热身了,也就是说,将同步NSURLConnections包装在NSOperation中并抛出到队列中。对于创建异步web服务调用框架的问题,该解决方案可能是一个更直接的解决方案,尽管我的方法+您的见解仍然是可行的。请回复我之前的评论。这种方法就是我在NSO操作中使用vs同步NSURLConnections的方法。NSURLConnection已经提供了所需的线程,而无需将其放入NSO操作中。另外,在阅读了更多的博客之后,同步NSURLConnections+身份验证并不像异步调用那样提供那么多的“钩子”。文档只是一直说它是在别处声明的,但没有给出如何声明的信息。它是声明此代码的类的属性或ivar。应该可以通过
[self receivedData]
Nice访问它!我从未想过在NSO操作中包装同步NSURLConnection调用的方法。我认为这将是我正在寻找的解决方案。但是,使用此解决方案,您需要一种检索信息的方法。这里有一个链接指向这个问题的另一个SO答案:为了传递结果,我通常通过一个单例将数据结果存储在中心的某个位置,和/或将对象传递回任何对封装在通知中感兴趣的人(您可以在notification userInfo字典中封装任何对象)。