我搜索了高低,找到了很多答案,但没有一个有效。这可能是一件简单的事情,但它让我不知所措。以下是我的代码的一部分。我在viewDidLoad方法中为变量赋值,但它返回" null"当我尝试在另一种方法中使用它时。
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *returnedTN = TN;
JSONLoaderSched *jsonLoaderSched = [[JSONLoaderSched alloc] init];
NSURL *url = [NSURL URLWithString:@"http:scheduleA.json"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
teamSched = [jsonLoaderSched teamsFromJSONFile:url selectedTeam:returnedTN];
subArray = [teamSched objectAtIndex:0];
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(@"%@",teamSched);
NSLog(@"%@",subArray);
return [subArray count];
}
我使用viewDidLoad中的这些变量运行NSLog,并打印出他们应该使用的内容。但是当我从第二种方法做同样的事情时,他们都返回" null"。我很欣赏这个指导。
答案 0 :(得分:2)
首先,您正在做一件危险的事情:您在后台线程上设置这些实例变量的值,并在主线程上获取它们。
这也是问题的核心。问题是,因为你正在使用后台线程来设置它们,你在之前得到它们后台线程有机会设置它们,所以当然它们是仍然无效。
解决方案是:在viewDidLoad
中设置这些变量之后(请将它们设置在主线程上!),现在调用reloadData
(仍在主线程上)。这将导致表方法再次被调用 ,现在你有了数据。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// get your data in the background
id temp = [jsonLoaderSched teamsFromJSONFile:url selectedTeam:returnedTN];
// now get back on the main thread!!!!
dispatch_async(dispatch_get_main_queue(), ^{
teamSched = temp;
subArray = [teamSched objectAtIndex:0];
[self.tableView reloadData];
});
});
答案 1 :(得分:0)
网络访问发生在后台线程上。您需要在完成后重新加载表视图,并且为了线程安全,您需要设置ivars并在主线程上重新加载。
因为UIViewControllers是线程释放不安全的,所以你需要跳过weakSelf/strongSelf hoop以避免罕见但难以调试的崩溃。 (否则,可能会在后台线程上发生 - 释放,这意味着-dealloc可能会在后台线程上发生,除了在主线程上执行大量清理之外并不安全。)
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *returnedTN = TN;
JSONLoaderSched *jsonLoaderSched = [[JSONLoaderSched alloc] init];
__weak __typeof__(self) weakSelf = self;
NSURL *url = [NSURL URLWithString:@"http://adasoccerclub.org/scheduleA.json"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
id sched = [jsonLoaderSched teamsFromJSONFile:url selectedTeam:returnedTN];
dispatch_async(dispatch_get_main_queue(), ^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf) {
strongSelf->teamSched = sched;
strongSelf->subArray = [schedobjectAtIndex:0];
[strongSelf.tableView reloadData];
}
};
});
}
(我不知道Apple希望普通程序员如何做到这一点。)