为什么在使用__block标识符设置属性时应用程序崩溃

时间:2014-08-04 01:58:19

标签: ios crash testflight

我试图用这段代码设置一个UITextView的文本属性,但我发现一个崩溃,说我不能从主线程中做到这一点:

__block NSString *stringForText;

self.uploadTask = [upLoadSession uploadTaskWithRequest:request fromData:body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // ...
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
    int errorCode = httpResponse.statusCode;
    NSString *errorStatus = [NSString stringWithFormat:@"%d",errorCode];

    NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSString *totalResponse = [errorStatus stringByAppendingString:responseString];

    stringForText = totalResponse;
    [self updateView:stringForText];

    // 4
    self.uploadView.hidden = NO;
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}];


// 5
[_uploadTask resume];
}

-(void)updateView:(NSString*)texto{
    self.myTextView.text = texto;
}

为什么它崩溃说我无法在TestFlight的主线程中调用它?

3 个答案:

答案 0 :(得分:0)

确保您在主线程上完成所有工作。上传完成后,调入主队列:

__block NSString *stringForText;

self.uploadTask = [upLoadSession uploadTaskWithRequest:request fromData:body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    dispatch_async(dispatch_get_main_queue(), ^(void) {

        // ...
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
        int errorCode = httpResponse.statusCode;
        NSString *errorStatus = [NSString stringWithFormat:@"%d",errorCode];

        NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSString *totalResponse = [errorStatus stringByAppendingString:responseString];

        stringForText = totalResponse;
        [self updateView:stringForText];

        // 4
        self.uploadView.hidden = NO;
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    });
}];


// 5
[_uploadTask resume];

答案 1 :(得分:0)

再次检查。您必须从主线程更新UI。您的上传完成处理程序可能正在主线程上运行。如果您想从任何线程调用updateView:,那么您可以将标签的操作分配给主线程:

-(void)updateView:(NSString*)texto{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.myTextView.text = texto;
    });
}

答案 2 :(得分:0)

它正在崩溃,因为你的块正在后台线程上被调用,并且需要在主线程上修改UI元素。

像[{1}}

一样包裹[self updateView:stringForText];