Pregunta

Tengo problemas para disparar un comando perforeSelector después del control, tras la detección de un acelerómetro 'Flick'. Se detecta el movimiento ('Got aquí' está registrado), pero por alguna razón el selector pasó al comando performselector no está disparando.

Configuré un bloque de pruebas y ejecuté con éxito un performador a partir de eso, por lo que no creo que los bloques en sí mismos estén causando el problema, ¿tal vez tiene algo que ver con el hilo en el que Coremotion está funcionando? (Debo admitir que es un poco confuso en bloques/hilos/coreMotion)

Cualquier pista sería muy apreciada. Gracias.

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Do any additional setup after loading the view, typically from a nib.

    motionManager = [[CMMotionManager alloc] init];
    if(motionManager.accelerometerAvailable)
    {
        motionManager.accelerometerUpdateInterval = 0.1;
        NSOperationQueue *motionQueue = [[NSOperationQueue alloc] init]; 
        [motionManager startAccelerometerUpdatesToQueue: motionQueue withHandler: ^(CMAccelerometerData *data, NSError *error) 
         {
             float accelerationThreshold = 1.2;

             CMAcceleration userAcceleration = data.acceleration;
             if (fabs(userAcceleration.x) > accelerationThreshold)               
             {
                 NSLog(@"Got here"); //runs
                 [self performSelector:@selector(test) withObject:nil afterDelay:1.0];
             }
         }];
    }
}

-(void) test
{
    NSLog(@"perform selector after delay worked"); //doesn't run
}
¿Fue útil?

Solución

Llegué allí al final (después de tocar primero con la idea de cambiar a usar el método UIACCelerator para acceder al acelerómetro, pero luego descubrir que esto se desaprece en futuras versiones de iOS (consulte la sección "Tipos de eventos de movimiento" aquí)

Básicamente, el código en el bloque, ejecutado cuando se detecta el movimiento, no puede ejecutarse en el hilo principal, lo que puede causar problemas, especialmente con el código relacionado con UIView.

La forma de garantizar que el código se ejecute en el hilo principal es llamar:

[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:false]; 

En lugar de lo normal:

[self performSelector:@selector(test) withObject:nil afterDelay:1.0]; 

Oh, encontré la solución en un extracto de Google Books de lo excelente Desarrollo inicial del iPhone 4: explorando el iOS SDK. Esperemos que esto sea de alguna utilidad para las personas que luchan en la misma área, no dude en comentar si desea más información / código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top