0

我在尝试为我的NSURLConnection请求创建自定义URLConnectionDataDelegate时被卡住了。问题是我可以创建一个实现委托协议的类并发出请求:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:myDelegate];

但是在委托函数中,例如(void)connectionDidFinishLoading:(NSURLConnection *)connection,我必须修改一些 UI 元素,但我不知道该怎么做。

4

2 回答 2

1

如果您有一个实现该协议的专用类(不是 UIViewController 类),则NSURLConnectionDelegate不应修改connectionDidFinishLoading:方法中的 UI 元素。此方法用于“连接”类的“内部”使用。

您需要的是一种从“连接”对象获取请求最终结果的方法。也就是说,响应数据或 - 可能 - 一个错误。

实现此目的的一种方法是在您的“连接”类中提供一个属性,该属性采用完成块,当连接完成时,您的类将调用此块。

typedef void (^completion_block_t)(id result);

@property (nonatomic, copy) completion_block_t completionHandler;

然后,每当您的连接完成时(无论出于何种原因),您都会调用该块,其结果是响应数据(可能NSMutableData包含累积的数据块)或NSError您从连接中获得或自己创建的对象 - 例如当您没有获得正确的 Content-Type 或连接实际完成的时间,但状态代码并不意味着您的应用程序逻辑中的请求成功。

一个如何在视图控制器中使用它的示例:

// somewhere in your UIViewController:    
MyConnection* con = [[MyConnection alloc] initWithRequest:request];
__weak MyViewController* weakSelf = self;  // idiom to avoid circular references
con.completionHandler = ^(id result){
    if (![result isKindOfClass:[NSError error]]) {
        // do something with the response data:
        NSString* string = [[NSString alloc] initWithData:result 
                                                 encoding:NSUTF8StringEncoding];
        dispatch_async(dispatch_get_main_queue(), ^{
             // UIKit methods:
            weakSelf.myLabel.text = string;
        });
    }
    else {
        // Error
    }
};

// Start the connection:
[con start];
于 2013-07-07T23:04:46.780 回答
0

您可以让您的视图控制器成为委托并在回调中修改 UI 元素,或者在发生更新时让自定义委托对象向视图控制器发送消息。后者可以使用 KVO/绑定、通知、委托、块或其他方式来完成。

于 2013-07-07T16:43:01.543 回答