Search code examples
objective-cioscore-motion

Why do Core Motion updates not work when called through another object in this code?


@interface Tester()
{
    int currentAccelerationOnYaxis;
}    
@end

@implementation Tester

-(void) test
{
    CMMotionManager *motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 0.01;
    [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
                                       withHandler:^(CMDeviceMotion *motion, NSError *error)
                                       {
                                           currentAccelerationOnYaxis = motion.userAcceleration.y;
                                       }
    ];
    while(1==1)
    {
        NSLog(@"current acceleration is: %f", currentAccelerationOnYaxis);
    }
}
@end

I then execute the above method on a background thread like this :
[myTester performSelectorInBackground:@selector(test) withObject:nil];

and it works fine.

However, the following configuration is not working and I can't figure out why :

@implementation MotionHandler

@synthesize accelerationOnYaxis; // this is an int property of the MotionHandler class

-(void) startAccelerationUpdates
{
    CMMotionManager *motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 0.01;
    [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
                                       withHandler:^(CMDeviceMotion *motion, NSError *error)
                                       {
                                           self.accelerationOnYaxis = motion.userAcceleration.y;
                                       }
    ];
}

@implementation Tester

-(id)init
{
    //...
    currentMotionHandler = [[MotionHandler alloc] init];
}
-(void) test
{
    [currentMotionHandler startAccelerationUpdates];
    while(1==1)
    {
        NSLog(@"current acceleration is: %f", currentMotionHandler.accelerationOnYaxis);
    }
}
@end

I then execute the above method on a background thread like this :
[myTester performSelectorInBackground:@selector(test) withObject:nil];

and it's not working, why is that ?


Solution

  • I figured it out. In my 2nd version the CMMotionManager instance I was creating got lost for some reason. Therefore, I changed the implementation of my MotionHandler class into this :

    MotionHandler.m

    @interface MotionHandler()
    {
       //..
       CMMotionManager *motionManager; // I now declare it here
    }
    
    @implementation MotionHandler
    
    @synthesize accelerationOnYaxis; // this is an int property of the MotionHandler class
    
    -(void) startAccelerationUpdates
    {
        motionManager = [[CMMotionManager alloc] init]; // and then initialize it here..
        motionManager.deviceMotionUpdateInterval = 0.01;
        [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
                                           withHandler:^(CMDeviceMotion *motion, NSError *error)
                                           {
                                               self.accelerationOnYaxis = motion.userAcceleration.y;
                                           }
        ];
    }
    -(void)test
    {
        [self startAccelerationUpdates];
        while(1==1)
        {
            NSLog(@"current acceleration on y-axis is: %f", self.accelerationOnYaxis);
        }
    }
    

    and now it seems to be working fine.