Domanda

Ho difficoltà a sparare un comando di AfterDelay, dopo il rilevamento di un "film" dell'accelerometro. Il movimento viene rilevato ("Get Here" è registrato), ma per qualche motivo il selettore passato al comando performSelector non sta sparando.

Ho impostato un blocco di prova e ho eseguito con successo un performance da quello, quindi non credo che i blocchi si stiano causando il problema, forse ha qualcosa a che fare con il filo su cui è in esecuzione la coremozione? (Devo ammettere di essere leggermente confuso su blocchi/thread/coremotion)

Qualsiasi indizio sarebbe molto apprezzato. Grazie.

- (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
}
È stato utile?

Soluzione

Sono arrivato lì alla fine (dopo aver giocato prima con l'idea di passare all'utilizzo del metodo Uaccicerator per accedere all'accelerometro, ma poi scoprendo che questo deve essere deprecato nelle future versioni di iOS (vedere la sezione "Tipi di eventi di movimento" qui)

Fondamentalmente il codice nel blocco, eseguito quando viene rilevato il movimento, potrebbe non essere eseguito sul thread principale, che può causare problemi, in particolare con il codice correlato a UIView.

Il modo per garantire che il codice venga eseguito nel thread principale è chiamare:

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

Invece del normale:

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

Oh, ho trovato la soluzione in un estratto di Google Books dall'aspetto eccellente IPPHIPONE Sviluppo di iPhone 4: esplorare l'SDK iOS. Spero che questo possa essere di qualche utilità per le persone che lottano nella stessa area, sentiti libero di commentare se desideri ulteriori informazioni / codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top