I was just having this same problem, and wouldn't you know it, the solution was in the documentation ;)
The problem is with the block format. All of the tutorials seem to favor that method, but Apple recommends periodic polling of the CMMotionManager
as a more performance oriented approach. The block format adds overhead.
From the CMMotionManager
Class Reference:
To handle motion data by periodic sampling, the app calls a “start” method taking no arguments and periodically accesses the motion data held by a property for a given type of motion data. This approach is the recommended approach for apps such as games. Handling accelerometer data in a block introduces additional overhead, and most game apps are interested only the latest sample of motion data when they render a frame.
So what you want to do, from the docs again:
Call startAccelerometerUpdates to begin updates and periodically access CMAccelerometerData objects by reading the accelerometerData property.
Something along these lines
CMMotionManager *mManager = [(AppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];
[mManager startAccelerometerUpdates];
Then, in some sort of periodically updating method of your choosing:
CMMotionManager *mManager = [(SEPAppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];
CMAccelerometerData *aData = mManager.accelerometerData;
This solution appears to work as well as UIAccelerometer
on an iPhone 4 from the limited testing I've done.