尝试在iOS中使用Singleton模式重构网络方法

时间:2015-11-01 06:30:17

标签: ios objective-c uitableview objective-c-blocks

我的应用程序中有以下方法,它使用String[] elements = xml.split("<"); LinkedList<String> ll = new LinkedList<String>(); for (String str : elements) { if (str.isEmpty()) continue; str = str.trim(); if (ll.isEmpty()) { ll.add(str); continue; } if (!ll.peekLast().equals(str)) { ll.add(str); } } while (!ll.isEmpty()) { System.out.println("<" + ll.pollFirst()); } 从JSON格式的Web服务中提取电影数据:

NSURLSession

上面的代码工作正常。没有问题。但是,我现在要做的是重构我的代码,以便在包含我的- (void) downloadMovieData { //this is just a visual cue to show that processing is being done [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; //creating the request NSURL *url = [NSURL URLWithString:kMovieURL]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; //creating the session self.config = [NSURLSessionConfiguration defaultSessionConfiguration]; self.session = [NSURLSession sessionWithConfiguration:self.config]; //the object that makes the call to the web service using the request and the session, and returns a response or an error NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { //At this point a response has been received, so we can turn the indicator off [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; //I am casting the response to an NSHTTPURLResponse so I can check the status code of the response NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; //a status code of 200 means a successful connection with the web service if (httpResponse.statusCode == 200) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"Success!"); //I send the data that was received from the response to the method so that the JSON data is extracted [self populateArray:data]; }); } else { NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"Received HTTP %ld: %@", (long)httpResponse.statusCode, result); } }]; [task resume]; } - (void) populateArray: (NSData *)data { NSError *jsonError; NSDictionary *response =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; if (response) { self.movieObjects = response[@"movies"]; NSLog(@"The movie objects are: %@", self.movieObjects); [self.tableView reloadData]; } else { NSLog(@"ERROR: %@", jsonError); } } 委托方法的类中包含所有网络代码,我想将代码移动到使用Singleton的单独类中更好地分离代码的方法。我有以下框架代码,如下所示:

UITableView

我完全理解Singleton类没有问题。这不是问题。我的问题是理解如何理解&#34;完成处理程序&#34;这个方法的一部分:

#import "Networker.h"

@implementation Networker

+ (NSURLSession *)dataSession {
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    });
    return session;
}

+ (void)fetchContentsOfURL:(NSURL *)url completion:(void (^)(NSData *data, NSError *error)) completionHandler {

    NSURLSessionDataTask *dataTask = [[self dataSession] dataTaskWithURL:url
                      completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {

         if (completionHandler == nil) return;

         if (error) {
             completionHandler(nil, error);
             return;
         }
         completionHandler(data, nil);
     }];

    [dataTask resume];
}

我想做的是将我在方法中的代码移动到&#34; downloadMovieData&#34;,进入&#34; fetchContentsOfURL&#34;,并返回一个+ (void)fetchContentsOfURL:(NSURL *)url completion:(void (^)(NSData *data, NSError *error)) completionHandler {} 对象然后我可以使用在我的调用类中填充UITableView。但是,在这样做的过程中,我想确保我理解&#34; completionHandler&#34;这种新方法的一部分。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

你不能移动它所以它返回,因为它是异步的。从技术上讲,你可以,但是在你等待的时候你会阻塞主线程。

相反,您只需用对单例的调用替换当前代码,在完成块中调用其他方法来处理数据。

需要注意的事项:

  1. 最好在你的单身人士调用某个完成程序块之前调派你的单身人士,这样你就不需要该职能的所有用户记住这样做了
  2. 它不需要是单例,您可以在每次需要时实例化该类的副本或使用依赖注入,这两者通常都提供更好的架构