1

NSURL リクエストの結果に応じてインターフェイスを更新するアプリがあります。現在のView Controllerが「ProfileViewController」と呼ばれる場合にのみ、アプリがフォアグラウンドになったときにリクエストが発生するように設定しました。

私の問題は、アプリをバックグラウンドから戻すたびに、インターフェイスが数秒間ロックすることです。メイン/バックグラウンド スレッドを完全に理解しようとしていますが、NSURL チェックの実行中にアプリの応答性を維持するために何ができるかわかりません。どんな援助も素晴らしいでしょう!ありがとう!

私の見解では、方法をロードしました:

-(void)viewDidLoad {

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(appReturnsActive) name:UIApplicationDidBecomeActiveNotification
    object:nil];

    //additional code
}

次に、アプリで Active メソッドを返します。

- (void)appReturnsActive {

    [myTimer invalidate];
    myTimer = nil;

    //ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
    UIViewController *currentVC = self.navigationController.visibleViewController;
    NSString * name = NSStringFromClass([currentVC class]);
    if ([name isEqualToString:@"ProfileViewController"]) { 

        [activityIndicator startAnimating];
        [activityIndicatorTwo startAnimating];
        locationManagerProfile.delegate = self;
        locationManagerProfile.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManagerProfile startUpdatingLocation];    
    }
}

最後に、Did Update Location メソッドで、ユーザーと場所の間の距離を取得します。結果が 1 の場合は、インターフェイスを更新して別のボタンを表示します。これは、インターフェイスがフリーズする場所です。

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
*)newLocation fromLocation:(CLLocation *)oldLocation {

    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {

        [self performSelectorOnMainThread:@selector(buttonUpdate:)
        withObject:NULL waitUntilDone:NO];

    }
}

新しい方法:

-(void)buttonUpdate {

NSString *userLongitude =[NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.longitude];
        NSString *userLatitude = [NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.latitude];
        [locationManagerProfile stopUpdatingLocation];
        NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"savedLatitude"];
        NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
                                    stringForKey:@"savedLongitude"];
        NSString *distanceURL = [NSString 
        stringWithFormat:@"http://www.website.com/page.php?
        lat1=%@&lon1=%@&lat2=%@&lon2=%@",userLatitude, userLongitude, placeLatitude, 
        placeLongitude];

        NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
        URLWithString:distanceURL]];

        NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult 
        encoding:NSUTF8StringEncoding];

        if ([distanceInFeet isEqualToString:@"1"])
        {
            UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:@"Button 1" 
            style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionTwo)];
            self.navigationItem.rightBarButtonItem = btnGo;

            UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:@"Button 
            Two" style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionOne)];
            self.navigationItem.rightBarButtonItem = btnGoTwo;

            self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo, 
            btnGoTwo, nil];
        }
}
4

2 に答える 2

0

CoreLocation デリゲート メソッド (例: " didUpdateToLocation" など) はすべてバックグラウンドでセカンダリ スレッドで実行されますが、UI 関連はすべてメイン スレッドで実行する必要があります

問題を解決するには、メイン スレッドで UI を変更する必要があります。使用できる便利な基盤 API の 1 つは次のとおりです。

performSelectorOnMainThread:withObject:waitUntilDone:

performSelectorOnMainThread問題を解決するには、ボタン作成コードを別のメソッドに移動し、古いメソッド (CoreLocation デリゲート プロトコルを介して別のスレッドで呼び出される) から" " を介してその新しいメソッドを呼び出します。

于 2013-06-21T10:05:10.223 に答える
0
NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
    URLWithString:distanceURL]];

同期呼び出しです。これは、コードがネットワーク呼び出しの結果が続くのを待つことを意味します。NSURLConnection ( http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html ) または AFNetworkingを使用して、非同期リクエストを行う必要があります。

于 2013-06-21T10:31:28.160 に答える