gpt4 book ai didi

iphone - 为什么 popViewController 每隔一段时间才起作用

转载 作者:行者123 更新时间:2023-12-03 18:47:51 26 4
gpt4 key购买 nike

我完全被难住了,情况是这样的:

我的应用程序使用核心位置框架来获取用户的当前位置,然后 ping 我的服务器 TrailBehind附近有趣的地方并将它们显示为列表。没问题。

为了节省电池,我在从服务器获取数据后关闭 GPS 服务。如果用户在使用应用程序时移动并想要一个新列表,他可以单击导航 Controller 上的“刷新”,然后再次激活 CLLocation 服务,将从服务器检索一批新数据并重新绘制表格。

当应用程序从我的服务器获取数据时,我会加载一个加载屏幕,上面有一个旋转的地球仪,上面写着“正在加载,请稍候”,并且我隐藏了导航栏,这样他们就不会点击“后退”。

因此,从服务器获取的初始数据顺利进行。

第一次点击刷新时,所有代码都会执行以获取新位置,再次 ping 服务器以获取新的数据列表并更新单元格。但是,它没有按应有的方式加载 TableView ,而是恢复 TableView 的导航 Controller 栏,但仍然在主窗口中显示我的加载 View 。这仅在设备上有效,在模拟器中一切正常。

我第二次点击刷新时,功能正常工作。

我第三次点击刷新时,它失败了,如上所述。

我第四次点击刷新,它工作正常。

我第五次点击刷新时,它失败了,如上所述。

等等,偶数刷新成功,奇数刷新失败。我逐行检查了所有代码,一切似乎都正常执行。实际上,我继续单步执行核心指令,在大量点击“单步”之后,我发现 TableView 实际上在 CFRunLoopRunSpecific 的某个时刻显示在屏幕上,但随后我单击了“继续”,我的加载 View 接管了屏幕。

我完全困惑了。请帮忙!!非常感谢您的见解。

Video of the strange behavior:

相关代码:

RootViewControllerMethods(这是此 TableView 项目的基础 View )

- (void)viewDidLoad {
//Start the Current Location controller as soon as the program starts. The Controller calls delegate methods
//that will update the list and refresh
[MyCLController sharedInstance].delegate = self;
[[MyCLController sharedInstance].locationManager startUpdatingLocation];
lv = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil];
[self.navigationController pushViewController:lv animated:YES];
[super viewDidLoad];
}



- (void)updateClicked {
//When the location is successfully updated the UpdateCells method will stop the CL manager from updating, so when we want to update the location
//all we have to do is start it up again. I hope.
[[MyCLController sharedInstance].locationManager startUpdatingLocation];
[self.navigationController pushViewController:lv animated:YES];
//LV is a class object which is of type UIViewController and contains my spinning globe/loading view.
}



-(void)updateCells {
//When the Core Location controller has updated its location it calls this metod. The method sends a request for a JSON dictionary
//to trailbehind and stores the response in the class variable jsonArray. reloadData is then called which causes the table to
//re-initialize the table with the new data in jsonArray and display it on the screen.

[[MyCLController sharedInstance].locationManager stopUpdatingLocation];

if(self.navigationController.visibleViewController != self) {
self.urlString = [NSString stringWithFormat:@"http://www.trailbehind.com/iphone/nodes/%@/%@/2/10",self.lat,self.lon];
NSURL *jsonURL = [NSURL URLWithString:self.urlString];
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];
NSLog(@"JsonData = %@ \n", jsonURL);
self.jsonArray = [jsonData JSONValue];
[self.tableView reloadData];
[self.navigationController popToRootViewControllerAnimated:YES];
[jsonData release];
}
}

CLController 方法:基本上只是将所有数据直接发送回 RootViewController

// Called when the location is updated
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(@"New Location: %@ \n", newLocation);
NSLog(@"Old Location: %@ \n", oldLocation);
@synchronized(self) {
NSNumber *lat = [[[NSNumber alloc] init] autorelease];
NSNumber *lon = [[[NSNumber alloc] init] autorelease];
lat = [NSNumber numberWithFloat:newLocation.coordinate.latitude];
lon = [NSNumber numberWithFloat:newLocation.coordinate.longitude];
[self.delegate noteLat:lat];
[self.delegate noteLon:lon];
[self.delegate noteNewLocation:newLocation];
[self.delegate updateCells];
}
}

最佳答案

第一个想法是,您可能不想在推送加载 View 之前将 startUpdatingLocation 发送到 CLLocationManager。通常,第一条 -locationManager:didUpdateToLocation:fromLocation: 消息将立即出现,并包含缓存的 GPS 数据。仅当您对每条消息进行操作并且不过滤 GPS 数据(如此处的示例代码所示)时,这才重要。但是,这不会导致您所描述的情况 - 它会导致加载屏幕卡住。

我在不同的情况下经历过类似的奇怪行为,当切换到不同的选项卡时我试图弹出到 Root View Controller ,并且调用没有在正确的位置进行。我相信 popToRootViewController 被我调用了两次。我怀疑您的加载 View 要么被推送两次,要么弹出两次。

我建议在 LoadingViewController 中以最少的日志记录实现 -viewWillAppear:、-viewDidAppear:、-viewWillDisappear: 和 -viewDidDisappear:。

- (void)viewWillAppear:(BOOL)animated {
NSLog(@"[%@ viewWillAppear:%d]", [self class], animated);
[super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
NSLog(@"[%@ viewDidAppear:%d]", [self class], animated);
[super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"[%@ viewWillDisappear:%d]", [self class], animated);
[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated {
NSLog(@"[%@ viewDidDisappear:%d]", [self class], animated);
[super viewDidDisappear:animated];
}

然后,在您的设备上运行测试,看看它们是否总是被发送到您的 View Controller 以及发送频率。您可以向 -updateClicked 添加一些日志记录以显示双击。

另一个想法,虽然您的 @synchronized block 是一个好主意,但它只会阻止其他线程执行这些语句,直到第一个线程退出该 block 。我建议将 -stopUpdatingLocation 消息移至 @synchronized block 内的第一个语句。这样,一旦您决定对一些新的 GPS 数据采取行动,您立即告诉 CLLocationManager 停止发送新数据。

关于iphone - 为什么 popViewController 每隔一段时间才起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/818605/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com