调度队列和全局 NSMutableDictionary - 目标 C [英] Dispatch Queue and global NSMutableDictionary - Objective C
问题描述
我正在尝试使用调度队列中的全局 NSMutableDictionary.但是,这些项目不断返回 NULL.
I'm trying to use a global NSMutableDictionary from a dispatch queue. However, the items keep coming back NULL.
我想要做的是使用 dispatch_queue 访问外部 json 文件,然后使用此信息填充 UITableView.
What I'm trying to do is access an external json file with a dispatch_queue, then populate a UITableView with this info.
这是我所拥有的
vc.h:
@interface viewcontroller {
NSMutableDictionary *jsonArray;
}
vc.m:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define jsonTest [NSURL URLWithString:@"http://www.sometest.com/test.php"]
-(void)viewDidLoad {
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
jsonTest];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
// if I run the log here, I can access jsonArry and the log prints correctly
NSLog(@"City: %@", [jsonArray objectForKey:@"city"];
});
}
-(NSMutableDictionary *)fetchedData:(NSData *)responseData {
NSError *error;
jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
return jsonArray;
}
/********************* Table formatting area **********************/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.ipTable) {
if ([ipArray count] == 0){
return 1;
} else { // meta table
return [ipArray count];
}
} else { // IP Meta Data
return [jsonArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.myTable) {
NSString *CellIdentifier = NULL;
if ([ipArray count] == 0) {
CellIdentifier = @"No Cells";
} else {
CellIdentifier = @"IP Cell";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([ipArray count] == 0)
{
[cell.textLabel setText:NSLocalizedString(@"None Found", nil)];
return cell;
} else {
IPAddr *theip = [ipArray objectAtIndex: [indexPath row]];
NSString *theipname = [theip ipName];
if ([theipname isEqualToString:@""]) {
[cell.textLabel setText: [theip ipNum]];
[cell.detailTextLabel setText:NSLocalizedString(@"noName", nil)];
} else {
[cell.textLabel setText: [theip ipName]];
[cell.detailTextLabel setText: [theip ipNum]];
}
return cell;
}
} else { // meta table
static NSString *CellIdentifier = @"metaCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// jsonArray content would go here to fill the cells.
/******************** something here to fill the cells using jsonArray ********************/
return cell;
}
} // END UITAbleViewCell
如果我访问队列中的 jsonArray,它会正常返回并打印城市的日志.但是,如果我尝试在队列外使用它,它会返回 NULL.
If I access the jsonArray inside the queue, it returns fine and prints the log for the city. However, if I try to use it outside the queue, it returns NULL.
我想弄清楚发生了什么,有什么想法吗?
I'm trying to figure out what is happening, any ideas?
我需要在同一个视图的不同方法中使用 jsonArray,所以我需要它是全局的.
I need to use jsonArray in different methods in the same view, so I need it to be global.
推荐答案
我相当确定问题在于数据源方法 (numberOfRowsInSection
,cellForRowAtIndexPath
) 在后台线程完成之前被调用,并且填充 jsonArray
.因此你必须重新加载表格视图,当背景线程已完成:
I am fairly sure that the problem is that the data source methods (numberOfRowsInSection
,
cellForRowAtIndexPath
) are called before the background thread has finished and
filled the jsonArray
. Therefore you have to reload the table view when the background
thread has finished:
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:jsonTest];
NSError *error;
NSArray *tmpArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
dispatch_sync(dispatch_get_main_queue(), ^{
// Assign new data to data source and reload the table view:
jsonArray = tmpArray;
[self.metaTableView reloadData];
});
});
}
所以表视图最初是空的,当数据有后重新加载到了.
So the table view would be empty initially, and reloaded later when the data has arrived.
这篇关于调度队列和全局 NSMutableDictionary - 目标 C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!