开发者

Adapting Shake Code from 'Beginning Iphone 4 Development' Causing Crash

开发者 https://www.devze.com 2023-03-10 00:02 出处:网络
The code below is a near replica of the Shake and Bake example from Beginning Iphone 4 Development.It is lacking a BOOL if statement before CMAcceleration acceleration = accelerometerData.acceleration

The code below is a near replica of the Shake and Bake example from Beginning Iphone 4 Development. It is lacking a BOOL if statement before CMAcceleration acceleration = accelerometerData.acceleration; because I want the person to shake and refresh the results as many times as they want. I have a button that executes the same code fl开发者_如何学Goawlessly. When I run the code and shake the iphone, it crashes. What am I missing that will make this work? Can you not run the same code with a button as with the shake method?

Example.h

#import <CoreMotion/CoreMotion.h>
#define kAccelerationThreshold 1.7
#define kUpdateInterval (1.0f/10.0f)

@interface exampleViewController : UIViewController  {
CMMotionManager *motionManager;
}
@property (retain,nonatomic) CMMotionManager *motionManager;
@end

Example.m

@synthesize motionManager;

-(void)viewDidLoad {

self.motionManager = [[[CMMotionManager alloc] init] autorelease];
motionManager.accelerometerUpdateInterval = kUpdateInterval;
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[motionManager startAccelerometerUpdatesToQueue:queue
                                    withHandler:
 ^(CMAccelerometerData *accelerometerData, NSError *error){
     if (error) {
         [motionManager stopAccelerometerUpdates];
     } else {
         CMAcceleration acceleration = accelerometerData.acceleration;
         if (acceleration.x > kAccelerationThreshold 
            || acceleration.y > kAccelerationThreshold 
            || acceleration.z > kAccelerationThreshold){

// There is a bunch of other stuff here, but it all works using a button called shake....
            example4.hidden = NO;
            select1.text = first;
            display.text = [[NSString alloc] initWithFormat: @"%@", first];

         }
     }
 }];
}

- (void)dealloc
{
[super dealloc];
[motionManager release];
}

- (void)viewDidUnload {
[super viewDidUnload];
self.motionManager = nil;
}

@end


You are trying to create and display an alert view on a thread other than the main thread. UI updates are to be done in the main thread only. You should use performSelectorOnMainThread:withObject:waitUntilDone: to create and display on the main thread.

You can always add a request your UI updates like this –

dispatch_async(dispatch_get_main_queue(),^{
    // Put all your UI updates here; 
});


The part that looks fishy to me is NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];.

Nowhere are you hanging on to the queue for the duration of the time that motionManager is dispatching to it. I checked the documentation for startAccelerometerUpdatesToQueue but it doesn't say that the receiver retains the queue, so that's probably not something you can safely assume. My suggestion is to not autorelease the queue. Instead, release it in viewDidUnload after calling stopAccelerometerUpdates on motionManager.

0

精彩评论

暂无评论...
验证码 换一张
取 消