1

我需要从 URL 下载数据(这会以 JSON 格式打印数据)并将其存储在应用程序的 AppDelegate.m 文件中的应用程序“配置”文件中。当我运行该应用程序时,它只是出于某种原因跳过了 dispatch_async 代码。为什么会发生这种情况,我该如何解决?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Download the config.json file
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSString *configFileUrl = @"http://webserviceurl";
        //NSString *downloadToFile = @"Configuration.json";
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:configFileUrl]];
        [self performSelectorOnMainThread:@selector(writeDataToConfigurationJsonFile:) withObject:data waitUntilDone:YES];
    });

 //More code below

这就是我将数据写入应用程序 Documents 目录中的文件的地方:

-(void)writeDataToConfigurationJsonFile:(NSData*)jsonData{

    NSString *content = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    //get the documents directory:
    NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    //make a file name to write the data to using the documents directory:
    NSString *fileName = [NSString stringWithFormat:@"%@/Configuration.json", documentsDirectory];

    //save content to the documents directory
    [content writeToFile:fileName
              atomically:YES
                encoding:NSUTF8StringEncoding
                   error:nil];
}
4

4 回答 4

1

performSelectorOnMainThread是一个运行循环方法,你需要使用:

dispatch_async(dispatch_get_main_queue(), ^{/*code*/});
于 2013-06-20T23:15:45.250 回答
1

您可以在 dispatch_async() 中嵌套对 dispatch_sync() 的调用,以确保在下载数据后,将数据同步写入主线程。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Download the config.json file
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSString *configFileUrl = @"http://webserviceurl";
        //NSString *downloadToFile = @"Configuration.json";
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:configFileUrl]];

        dispatch_sync(dispatch_get_main_queue(), ^{
            [self writeDataToConfigurationJsonFile:data];
        });
    });
}
于 2013-06-20T23:48:11.640 回答
1

当您异步调度线程时,创建一个新的串行/并发队列。

对于同步调度,回到主队列(尝试不使用'waitUntilDone:YES'):

    dispatch_async(dispatch_queue_create("com.yourOrgName", DISPATCH_QUEUE_SERIAL), ^{

    NSString *configFileUrl = @"http://webserviceurl";
    //NSString *downloadToFile = @"Configuration.json";
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:configFileUrl]];
    dispatch_sync(dispatch_get_main_queue(), ^ {
    [self performSelector:@selector(writeDataToConfigurationJsonFile:)     withObject:data afterDelay:0.0f];

      });
     });
于 2013-06-21T04:54:43.610 回答
0

就本应用而言,最好的方法是使用同步请求而不是异步请求。这是最后的代码块 -

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"some url"]];
NSError        *error = nil;
NSURLResponse  *response = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *string = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(@"response");

NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:@"%@/Configuration.json", documentsDirectory];
//save content to the documents directory

[string writeToFile:fileName
         atomically:YES
           encoding:NSUTF8StringEncoding
              error:nil];
于 2013-06-21T18:44:16.847 回答