【问题标题】:Refactoring my code for asynchronous NSURLConnection为异步 NSURLConnection 重构我的代码
【发布时间】:2012-02-03 11:44:22
【问题描述】:

使用同步请求存在问题。问题是我不确定如何重构下面的代码以使用异步请求来完成以下两个任务:

  1. 使用UIActivityIndicatorView 子视图通知活动提取;
  2. 在连接请求之前实施Reachability检查,以确保存在互联网连接并且主机可用,即reachabilityWithHostName:@"wwww.mywebhostingisterrible.com"

目前我有一个 Fetcher 类和一个 +(Fetcher *)sharedFetcher 单例,在我的所有视图控制器中都使用它来获取数据。目前所有数据都是使用以下代码获取的:

- (NSString *)stringWithUrl:(NSURL *)url {

    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];

    NSData *urlData;
    NSURLResponse *response;
    NSError *error;

    urlData = [NSURLConnection sendSynchronousRequest:urlRequest
                                    returningResponse:&response
                                                error:&error];

    return [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];

}

获取的方法如下所示:

-(NSArray *)fetchDogFoodListing {
    NSString *urlString = [NSString stringWithFormat:@"%@query/dogFood/%@/%lli/%@/%@",self.connectionUrl,self.queryCriteria.dogFoodName,self.queryCriteria.dogFoodBrandId,self.queryCriteria.dogFoodIngredients,self.queryCriteria.dogFoodBrand];
    NSString *json = [self stringWithUrl:[NSURL URLWithString:urlString]];
    return [self.factory buildIKDogFoodArrayWithJSON:json];
}

来自UIViewController-(void)viewDidLoad 中的呼叫如下所示:

self.dogFoods = [[IKFetcher sharedFetcher] fetchDogFoodListing];

我曾考虑在这种情况下实施委托,但我对委托应该如何工作感到非常不安。我什至不确定它应该走哪条路。 Fetcher 是否应该有一个 FetcherDelegate 可以通知视图控制器何时完成,以便 UI 可以更新?视图控制器是否应该有一个委托,以便 fetcher 可以在完成工作时更新视图?

我确信根据我的问题,您可以看出我对委派缺乏经验,因此我将不胜感激。

【问题讨论】:

    标签: iphone ios cocoa uiactivityindicatorview delegation


    【解决方案1】:

    你可以这样做

    dispatch_async(queue, ^{
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
    
        NSData *urlData;
        NSURLResponse *response;
        NSError *error;
    
        urlData = [NSURLConnection sendSynchronousRequest:urlRequest
                                    returningResponse:&response
                                                error:&error];
        dispatch_async(dispatch_get_main_queue(), ^{
             //.. do stuff with data here...
        }
    }
    

    或者,如果您希望连接是同步的,您也可以在 dispatch_sync 中执行 sendSynchronousRequest 代码,尽管您确实应该尽可能地异步。

    【讨论】:

    • 是的,我应该提到我意识到这是一种可能性,但我想避免它并使用 NSURLConnection 可用的异步回调
    • 如果我们是同一个页面,您可以轻松地做这样的事情。我有一个类封装 NSURLConnection 并使用它的委托方法github.com/Machx/Zangetsu/blob/master/Source/CWURLRequest.m 你可以使用这段代码或做类似的事情。
    • 好东西...所以我的问题是,我将如何重构现有代码以使用您提供的一些实现?例如,现在我使用单行self.dogFoods = [[IKFetcher sharedFetcher] fetchDogFoodListing]; 很方便,因为实例方法-(NSArray *)fetchDogFoodListing 返回一个我感兴趣的NSArray。你建议我怎么做才能以这种方式返回东西?等待异步响应然后返回数据?
    • 如果你个人有这样的课程,我会有一个类似 [[IKFetcher sharedFetcher] fetchDogFoodListingWithCompletionBlock:^(NSData *data, NSError *error) { if(data){ [self setDogFoods:data ]; } else { //日志错误 } }];这样你就可以获取数据,当它准备好时,你可以调用完成块中需要的任何其他方法。
    【解决方案2】:

    您可能想看看 Mugunth Kumar 的出色框架:

    http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit

    我计划在我未来的项目中将它用于 NSURLConnection

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2018-01-23
      相关资源
      最近更新 更多