调度队列和全局 NSMutableDictionary - 目标 C [英] Dispatch Queue and global NSMutableDictionary - Objective C

查看:53
本文介绍了调度队列和全局 NSMutableDictionary - 目标 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆