iOS Objective-C NSURLSession 未更新 UI / 属性
iOS Objective-C NSURLSession not updating UI / property
我在 Objective-C iOS 应用程序中更新 UI 时遇到了一些问题。
我在 ViewController.
的 viewDidLoad 部分调用我的函数 fetchData
NSURLSession
成功获取数据,但是我无法更新 UI 中的 titleText 属性,即使它在主队列中也是如此。
我可以在 viewDidLoad 方法中更新 属性,所以我感觉这与异步请求有关。
但是我尝试了多种方法都没有成功,因此非常感谢您的帮助。
- (void) fetchData
{
NSString *strURl = @"www.url.com";
NSLog(@"%@",strURl);
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:strURl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
if (data == nil) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"error", nil)message:NO_CONNECTION_TEXT preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"ok", nil) style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
return ;
}
else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!parsedDetails){
parsedDetails = [[NSMutableArray alloc]init];
}
parsedDetails = [provider parseJSON:data into:parsedDetails withResponse:response];
NSLog(@"%@",parsedDetails);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",parsedDetails);
NSLog(@"%@",[parsedDetails valueForKey:@"title"]);
self.titleText = [parsedDetails valueForKey:@"title"];
});
});
}
}] resume];
}
第 1 部分:确定标题
parsedDetails
是您代码中的 NSMutableArray
。
那么您正在该数组上使用 KVC(Key-Value 编码)方法 valueForKey
。
但这会 return 一个新数组。那里发生了什么:原始数组 (parsedDetails
) 中每个元素的 title
属性 的值作为新元素插入到新数组中,最终是 return编辑为数组。
由于您在上面的评论:
NSLog(@"%@",[parsedDetails valueForKey:@"title"]);
给出 return 值(一个包含一个字符串的数组):
("About")
但您真正想要的是第一个条目的标题元素,所以应该是这样的:
Detail *detail = parsedDetails.firstObject;
if (detail) {
title = [detail title];
} else {
title = @"default empty title";
}
或者如果您更喜欢 KVC 变体:
id detail = parsedDetails.firstObject;
if (detail) {
title = [detail valueForKey:@"title"];
} else {
title = @"default empty title";
}
第 2 部分:更新标签
据我了解你的评论,你有一个 NSString
属性 叫做 titleText
?大概是这样定义的:
@property (nonatomic, strong) IBOutlet NSString *titleText;
你在某处也有一个 UILabel
插座?
@property (weak, nonatomic) IBOutlet UILabel *label;
如果您只是更新本地字符串,它不会反映在 UI 中。您还必须将其转移到标签上。
看起来像这样:
self.label.text = self.titleText;
我在 Objective-C iOS 应用程序中更新 UI 时遇到了一些问题。
我在 ViewController.
的 viewDidLoad 部分调用我的函数 fetchDataNSURLSession
成功获取数据,但是我无法更新 UI 中的 titleText 属性,即使它在主队列中也是如此。
我可以在 viewDidLoad 方法中更新 属性,所以我感觉这与异步请求有关。
但是我尝试了多种方法都没有成功,因此非常感谢您的帮助。
- (void) fetchData
{
NSString *strURl = @"www.url.com";
NSLog(@"%@",strURl);
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:strURl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
if (data == nil) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"error", nil)message:NO_CONNECTION_TEXT preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"ok", nil) style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
return ;
}
else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!parsedDetails){
parsedDetails = [[NSMutableArray alloc]init];
}
parsedDetails = [provider parseJSON:data into:parsedDetails withResponse:response];
NSLog(@"%@",parsedDetails);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",parsedDetails);
NSLog(@"%@",[parsedDetails valueForKey:@"title"]);
self.titleText = [parsedDetails valueForKey:@"title"];
});
});
}
}] resume];
}
第 1 部分:确定标题
parsedDetails
是您代码中的 NSMutableArray
。
那么您正在该数组上使用 KVC(Key-Value 编码)方法 valueForKey
。
但这会 return 一个新数组。那里发生了什么:原始数组 (parsedDetails
) 中每个元素的 title
属性 的值作为新元素插入到新数组中,最终是 return编辑为数组。
由于您在上面的评论:
NSLog(@"%@",[parsedDetails valueForKey:@"title"]);
给出 return 值(一个包含一个字符串的数组):
("About")
但您真正想要的是第一个条目的标题元素,所以应该是这样的:
Detail *detail = parsedDetails.firstObject;
if (detail) {
title = [detail title];
} else {
title = @"default empty title";
}
或者如果您更喜欢 KVC 变体:
id detail = parsedDetails.firstObject;
if (detail) {
title = [detail valueForKey:@"title"];
} else {
title = @"default empty title";
}
第 2 部分:更新标签
据我了解你的评论,你有一个 NSString
属性 叫做 titleText
?大概是这样定义的:
@property (nonatomic, strong) IBOutlet NSString *titleText;
你在某处也有一个 UILabel
插座?
@property (weak, nonatomic) IBOutlet UILabel *label;
如果您只是更新本地字符串,它不会反映在 UI 中。您还必须将其转移到标签上。
看起来像这样:
self.label.text = self.titleText;