问题
I have a code block for my NSURLConnection sendAsynchronousRequest, and when I try to set a UILabel's text, the text is never set, even though the values are there. Here's my code:
NSString *address = [addresses objectAtIndex:indexPath.row];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@", address]]];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ([data length] > 0 && error == nil)
{
NSString *dataOfData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if(![dataOfData isEqualToString:@"ERROR: address invalid"]) {
[balanceLabel setText:[NSString stringWithFormat:@"Balance: %@", dataOfData]];
if(data) {
qrCodeButton.alpha = 1;
}
} else {
errorLabel.text = @"This address is invalid.";
}
}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
[balanceLabel setText:@"Server Error, Please Try Again"];
}
else if (error != nil){
NSLog(@"Error = %@", error);
}
}];
Why is the UILabel's text never set? Is there a limitation to code blocks? If so, how would I fix my problem? Cheers!
回答1:
It is because an NSOperationQueue is not the main thread. What you're doing is illegal. And the sad thing is that there is no need for it! Just say:
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// ... and the rest exactly as you have it now
All fixed. Your request is asynchronous on a background thread, but when it comes back to you on the completion handler, you'll be on the main thread and able to talk to the interface etc.
回答2:
Your code operates UI element should execute on main thread.
dispatch_async(dispatch_get_main_queue(), ^{
if ([data length] > 0 && error == nil)
{
NSString *dataOfData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if(![dataOfData isEqualToString:@"ERROR: address invalid"]) {
[balanceLabel setText:[NSString stringWithFormat:@"Balance: %@", dataOfData]];
if(data) {
qrCodeButton.alpha = 1;
}
} else {
errorLabel.text = @"This address is invalid.";
}
}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
[balanceLabel setText:@"Server Error, Please Try Again"];
}
else if (error != nil){
NSLog(@"Error = %@", error);
}
}) ;
Make sure errorLabel
is not nil and the UILabel
is visible (It is added in the view hierarchy and its frame is appropriate).
来源:https://stackoverflow.com/questions/21769545/set-uilabel-text-within-code-block