【问题标题】:Run http request on other thread on ios在 ios 上的其他线程上运行 http 请求
【发布时间】:2013-05-31 13:43:28
【问题描述】:

所以我希望我的应用在发送 http 请求并获得响应时不要锁定 GUI,我尝试了,但它抱怨我在主线程之外使用 uikit,有人可以告诉我正确的分离方法吗http 和 gui?

-(void)parseCode:(NSString*)title{

    UIActivityIndicatorView *spinner;
    spinner.center = theDelegate.window.center;
    spinner.tag = 12;
    [theDelegate.window addSubview:spinner];
    [spinner startAnimating];

    dispatch_queue_t netQueue = dispatch_queue_create("com.david.netqueue", 0);

    dispatch_async(netQueue, ^{
        NSString *url =[NSString stringWithFormat:@"http://myWebService.org/"];
        // Setup request
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:url]];
        [request setHTTPMethod:@"POST"];
        NSString *contentType = [NSString stringWithFormat:@"application/x-www-form-urlencoded"];
        [request addValue:contentType forHTTPHeaderField:@"Content-Type"];

        NSMutableString *data = [[NSMutableString alloc] init];
        [data appendFormat:@"lang=%@", @"English"];
        [data appendFormat:@"&code=%@", theDelegate.myView.text ];
        [data appendFormat:@"&private=True" ];
        [request setHTTPBody:[data  dataUsingEncoding:NSUTF8StringEncoding]];
        NSHTTPURLResponse *urlResponse = nil;
        NSError *error = [[NSError alloc] init];

        NSData *responseData = [NSURLConnection sendSynchronousRequest:request
                                             returningResponse:&urlResponse
                                                         error:&error];

        NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];


        dispatch_async(dispatch_get_main_queue(), ^{

            [spinner stopAnimating];
            [spinner removeFromSuperview];
            [self presentResults:result];
        });

    });

}

【问题讨论】:

  • 我没有看到变量spinner 被分配到哪里。

标签: ios uikit nsurlconnection grand-central-dispatch


【解决方案1】:

不要使用NSURLConnection:sendSynchronousRequest,而是使用NSURLConnection:initWithRequest:delegate:startImmediately:,它异步发送请求。使用NSURLConnection:connectionDidFinishLoading委托方法来处理响应。

Apple 在URL Loading System Programming Guide 中提供了一个示例。

如果您将startImmediately 设置为YES,则委托方法将在与调用请求的运行循环相同的运行循环中被调用。这很可能是您的主运行循环,因此您可以在委托方法中随意修改 UI,而不必担心线程问题。

【讨论】:

    【解决方案2】:

    我没看太多,但你总是可以尝试,

    [self performSelectorInBackground:@selector(parseCode:) withObject: title];
    

    该方法使函数在后台的单独线程上运行,并且实现起来并不费力,我在进行简单下载时使用它,例如 [NSData dataWithContentsOfURL:url];但如果你要做更大的事情,你可能需要做更多的工作。

    如果你需要在一个类的外部调用方法,那么你必须在类中创建一个方法来进行上面的调用,然后调用选择器

    【讨论】:

      【解决方案3】:

      我认为问题不在于您的 HTTP 代码 - 在于您从后台线程中访问 UI。特别是这一行:

      [data appendFormat:@"&code=%@", theDelegate.myView.text ];
      

      假设您正在访问UITextView 或类似的东西。您需要在后台线程之外执行此操作。将其移动到本地 NSString 变量中,然后您就可以从后台线程中安全地访问该变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-31
        相关资源
        最近更新 更多