私は完全に困惑しています、これが状況です:
私のアプリは Core Location フレームワークを使用してユーザーの現在の場所を取得し、TrailBehindでサーバーに ping を送信して近くの興味深い場所を探し、それらをリストとして表示します。問題はありません。
バッテリーを節約するために、サーバーからデータを取得した後、GPS サービスをオフにします。ユーザーがアプリの使用中に移動し、新しいリストが必要な場合、ナビゲーション コントローラーの [更新] をクリックすると、CLLocation サービスが再びアクティブになり、サーバーから新しいデータのバッチが取得され、テーブルが再描画されます。
アプリがサーバーからデータを取得している間、「読み込み中です。お待ちください」という地球儀が回転する読み込み画面を読み込み、「戻る」ボタンを押さないようにナビゲーション バーを非表示にします。
そのため、サーバーからの最初のデータ取得は問題なく行われます。
最初に更新を押したときに、すべてのコードが実行されて新しい場所が取得され、サーバーに再度 ping が実行されて新しいデータ リストが取得され、セルが更新されます。ただし、テーブル ビューをロードする代わりに、テーブル ビューのナビゲーション コントローラー バーを復元しますが、メイン ウィンドウにロード ビューを表示します。これはデバイスでのみ当てはまり、シミュレーターではすべてが正常に機能します。
リフレッシュ機能を2回目に押すと、機能が正常に機能します。
上記のように更新を3回目にすると失敗します。
リフレッシュを4回目にすると、正常に動作します。
上記のように更新を5回目にすると失敗します。
などなど、偶数のリフレッシュは成功し、奇数のリフレッシュは失敗します。すべてのコードを 1 行ずつ調べてみたところ、すべてが正常に実行されているようです。私は実際にコア命令をステップオーバーし続け、「ステップオーバー」を大量にクリックした後、CFRunLoopRunSpecificのある時点でテーブルビューが実際に画面に表示されることがわかりましたが、「続行」をクリックするとロードビューが引き継がれましたスクリーン。
私は絶対に困惑しています。助けてください!!あなたの洞察を前もって感謝します。
関連コード:
RootViewControllerMethods (これは、この TableView プロジェクトのベース ビューです)
- (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];
}
}