Почему popToRootViewContoller зависает или занимает много времени? - PullRequest
2 голосов
/ 05 декабря 2011

Я настроил некоторые виды с помощью контроллера навигации.Я хочу иметь возможность вернуться к исходному виду, когда я встряхиваю телефон.Во-первых, вот фрагмент кода, который есть в моем AppDelegate:

- (void)startAccelerometerUpdates
{

[motionManager startDeviceMotionUpdatesToQueue:queue withHandler:^(CMDeviceMotion *motion, NSError *error) {
    // based from 
    // /4713958/prostoe-obnaruzhenie-dvizheniya-iphone#4713984
    float accelerationThreshold = 1; // or whatever is appropriate - play around with   different values
    CMAcceleration userAcceleration = motion.userAcceleration;
    if (fabs(userAcceleration.x) > accelerationThreshold || 
        fabs(userAcceleration.y) > accelerationThreshold || 
        fabs(userAcceleration.z) > accelerationThreshold) {



        if(!self->isRoot) {
            NSLog(@"Stopping motion manager");
            [motionManager stopDeviceMotionUpdates];
            NSLog(@"popping to top view controller");
            [navcon popToRootViewControllerAnimated:YES];
            NSLog(@"Done popping");
        }

    }

}];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   .....

   motionManager = [[CMMotionManager alloc] init];
   motionManager.deviceMotionUpdateInterval = .5;

   isRoot = malloc(sizeof(BOOL));
   self->isRoot = NO;
   [self startAccelerometerUpdates];

   [navcon pushViewController:main animated:NO];
   ....
}

Я ожидал, что вызов popToRoot будет немедленным.Тем не менее, это занимает около 30 секунд.Интересно отметить, что кнопка сверху, которую вы можете нажать, чтобы вручную вернуться на предыдущую страницу, в данный момент не работает.Телефон, кажется, проделывает большую работу, чтобы заморозить кнопки.Итак, я определенно делаю что-то не так здесь.

Мне показалось, что, возможно, я продолжаю вызывать popToRootViewController несколько раз, поэтому я добавил проверку «isRoot», как вы видите в коде (пожалуйста, не отвлекайтесь на то, почему BOOL является указателем, у меня есть причина для этого).

1 Ответ

4 голосов
/ 05 декабря 2011

Ваш блок обработчика движения, похоже, предназначен для работы в фоновой очереди.Методы UIKit (например, popToRootViewController) следует вызывать только в основном потоке, и поведение, когда вы не соблюдаете это правило, часто похоже на то, что вы описали.

-performSelectorOnMainThread:withObject:waitUntilDone - это самый простой способ убедиться, чточто ваш код UIKit выполняется в основном потоке, но поскольку -popToRootViewControllerAnimated: принимает необъектный параметр, требуется немного больше работы.Самый простой способ - добавить еще один метод, который не принимает параметров:

-(void)popToRootView {
    [navcon popToRootViewControllerAnimated:YES];
}

, а затем обновить ваш блок для вызова этого метода в главном потоке:

if(!self->isRoot) {
    [motionManager stopDeviceMotionUpdates];
    [self performSelectorOnMainThread:@selector(popToRootView) withObject:nil waitUntilDone:NO];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...