未在iOS 6上第二次设置值。线程问题?
我正在编写一个iOS应用程序,它使用从服务器检索的数据填充数组,并在选择器视图中显示它 第一次显示视图时,一切都进展顺利;但是,当切换到另一个使用相机扫描内容的视图并使用滑出菜单(使用构建)切换回时,它无法填充阵列。后台任务完成检索记录后,当我们在UI线程上访问它时,会抛出一个未在iOS 6上第二次设置值。线程问题?,ios,objective-c,multithreading,networking,concurrency,Ios,Objective C,Multithreading,Networking,Concurrency,我正在编写一个iOS应用程序,它使用从服务器检索的数据填充数组,并在选择器视图中显示它 第一次显示视图时,一切都进展顺利;但是,当切换到另一个使用相机扫描内容的视图并使用滑出菜单(使用构建)切换回时,它无法填充阵列。后台任务完成检索记录后,当我们在UI线程上访问它时,会抛出一个NSRangeException,错误为索引0超出空数组的界限 我非常确定后台任务正在运行,并且在我将每个请求记录到服务器时成功地检索到了数据 我认为这可能是并发性和后台线程没有更新变量的问题 据我们测试,这个问题只出现在
NSRangeException
,错误为索引0超出空数组的界限
我非常确定后台任务正在运行,并且在我将每个请求记录到服务器时成功地检索到了数据
我认为这可能是并发性和后台线程没有更新变量的问题
据我们测试,这个问题只出现在iOS 6上,在iOS 7上没有发生,或者至少还没有发生
这是用于检索和设置数组的代码:
dispatch_queue_t queue = dispatch_queue_create("com.aaa.bbb", NULL);
dispatch_async(queue, ^{
_events = [_wi getEvents:_auth_token];
dispatch_async(dispatch_get_main_queue(), ^{
// code to be executed on the main thread when background task is finished
[_mPicker reloadComponent:0];
// Set the default on first row
[self pickerView:_mPicker didSelectRow:0 inComponent:0];
[pDialog dismissWithClickedButtonIndex:0 animated:YES];
});
});
这是mySidebarViewController
中的prepareforSegue
方法,用于在从滑出菜单中选择项目时在视图之间切换
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[_menuItems objectAtIndex:indexPath.row] capitalizedString];
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: @[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
}
}
视图从情节提要链接在一起以进行切换
当我尝试从pickerView:didSelectRow:incomonent:
方法中的events
数组中检索特定条目时,会发生此错误:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// Set the current id
_currentId = [NSString stringWithFormat:@"%d", row];
_currentName = [[_events objectAtIndex:row] objectForKey:@"event_name"];
-----------^
...
下面是正在运行的线程和调用堆栈的列表
根据我在安卓系统的经验,我认为这可能与我第一次没有正确完成后台任务有关,或者在后台任务之后应该运行的代码第二次与它一起运行
如果有任何建议能帮助我解决这个问题,我将不胜感激
感谢变量\u events
是从不同的线程访问的,没有任何同步机制
试试这个:
dispatch_queue_t queue = dispatch_queue_create("com.aaa.bbb", NULL);
dispatch_async(queue, ^{
NSArray* events = [_wi getEvents:_auth_token];
dispatch_async(dispatch_get_main_queue(), ^{
_events = [events copy];
// code to be executed on the main thread when background task is finished
[_mPicker reloadComponent:0];
// Set the default on first row
[self pickerView:_mPicker didSelectRow:0 inComponent:0];
[pDialog dismissWithClickedButtonIndex:0 animated:YES];
});
});
另外\u events
应该是NSArray
,而不是NSMutableArray
,以避免此类问题。谢谢您的回答。它解决了问题!我猜测它必须与变量锁和线程之间的同步有关,但我不确定如何解决它。