iOS代码跳过dispatch_async

时间:2013-06-20 23:12:14

标签: ios objective-c grand-central-dispatch

我需要从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 个答案:

答案 0 :(得分:1)

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

dispatch_async(dispatch_get_main_queue(), ^{/*code*/});

答案 1 :(得分: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];
        });
    });
}

答案 2 :(得分: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];

      });
     });

答案 3 :(得分: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];