目标 c - IOS变量返回"null" 在不同方法中使用时



我搜索了高低,找到了很多答案,但没有一个有效。 这可能是一些简单的事情,但它躲避了我。 下面是我的代码的一部分。 我在 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"。 我很感激你的指导。

首先,您正在做一件危险的事情:您在后台线程上设置这些实例变量的值并将它们放在主线程上。

这也是问题的核心。问题是,因为你使用后台线程来设置它们,所以你在后台线程有机会设置它们之前就得到了它们,所以当然它们仍然是空的。

解决方案是:在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];
    });
});

网络访问发生在后台线程上。您需要在表视图完成后重新加载表视图,并且为了线程安全,您需要设置 ivar 并在主线程上重新加载。

由于 UIViewControllers 是线程释放不安全的,因此您需要跳过 weakSelf/strongSelf 箍以避免罕见但难以调试的崩溃。(否则,-release 可能会发生在后台线程上,这意味着 -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];
      }
    };
  });
}

(我不知道苹果希望普通程序员如何做到这一点。

最新更新