我有多个 View 使用相同的NSURLRequest/NSURLConnection request。理想情况下,为了获得一些代码重用,我想使用某种“代理”来完成创建/执行(异步)请求/连接,设置所有委托(delegate)方法等的所有基础工作。 ,因此我不必在每个 View 中复制所有那些NSURLConnection委托(delegate)方法处理程序。首先,这种设计方法是否合理?第二,我将如何做这样的事情?

为了获得一些背景信息,我尝试了一下并使其“起作用”,但是,它似乎不是异步执行的。我创建了一个Proxy.h/m文件,该文件具有用于不同Web服务调用的实例方法(并且还包含NSURLConnection委托(delegate)方法):

@interface Proxy : NSObject {

    NSMutableData *responseData;
    id<WSResponseProtocol> delegate;
}

- (void)searchForSomethingAsync:(NSString *)searchString delegate:(id<WSResponseProtocol>)delegateObj;

@property (nonatomic, retain) NSMutableData *responseData;
@property (assign) id<WSResponseProtocol> delegate;

@end

WSResponseProtocol的定义如下:
@protocol WSResponseProtocol <NSObject>

@optional
- (void)responseData:(NSData *)data;
- (void)didFailWithError:(NSError *)error;

@end

要使用此功能, View Controller 只需要遵循WSResponseProtocol协议(protocol)即可捕获响应。进行Web服务调用的方式如下:
Proxy *p = [[Proxy alloc] init];
[p searchForSomethingAsync:searchText delegate:self];
[p release];

我可以提供更多代码,但可以假定其余代码。调用之前,我“startAnimating”一个UIActivityIndicatorView微调器。但是微调器从不旋转。如果我只是将NSURLConnection委托(delegate)方法直接放在 View Controller 中,则微调器将旋转。因此,这使我认为我的实现不是异步执行的。这里有什么想法/想法吗?

最佳答案

您的方法是合理的,但是,我不确定为什么要创建自己的协议(protocol)。这是没有必要的。实现此功能所需的一切都在Apple的documentation on 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
}

变量theConnection是我们的ivar。然后,您可以像这样检查它:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (connection == theConnection)
    {
        // do something with the data object.
        [connectionSpecificDataObject appendData:data];
    }
}

当然,您可以按照建议创建自己的协议(protocol)来实现它,然后调出符合协议(protocol)的委托(delegate),但是最好使用可以检查的成功和失败选择器实例化对象。像这样的东西:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (connection == theConnection)
    {
        if (delegate && [delegate respondsToSelector:successSelector])
            [delegate performSelector:successSelector
                           withObject:connectionSpecificDataObject];
    }
    [connection release];
}

其中dataDidDownloadSelector是在创建包含所有此代码的下载委托(delegate)时设置的SEL实例变量-您的Proxy对象。像这样的东西:
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
}

这已成为比我预期更长的答案。让我知道这是否没有道理,我可以尝试澄清。

此致,

10-07 19:13
查看更多