Адаптация кода встряхивания из «Начала разработки для iPhone 4» приводила к сбою - PullRequest
1 голос
/ 01 июня 2011

Приведенный ниже код является точной копией примера Shake and Bake из Beginning Iphone 4 Development. Отсутствует инструкция BOOL if перед ускорением CMAcceleration = accelerometerData.acceleration; потому что я хочу, чтобы человек встряхивал и обновлял результаты столько раз, сколько он хочет. У меня есть кнопка, которая выполняет тот же код без нареканий. Когда я запускаю код и встряхиваю iphone, он вылетает. Что мне не хватает, что заставит эту работу? Вы не можете запустить тот же код с помощью кнопки, что и с методом встряхивания?

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

Ответы [ 2 ]

1 голос
/ 01 июня 2011

Вы пытаетесь создать и отобразить представление оповещения для потока, отличного от основного потока. Обновления пользовательского интерфейса должны выполняться только в основном потоке. Вы должны использовать performSelectorOnMainThread:withObject:waitUntilDone: для создания и отображения в главном потоке.

Вы всегда можете добавить запрос на обновления вашего пользовательского интерфейса, как это -

dispatch_async(dispatch_get_main_queue(),^{
    // Put all your UI updates here; 
});
0 голосов
/ 02 июня 2011

Часть, которая мне кажется подозрительной, - NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];.

Нигде вы не удерживаетесь в очереди в течение времени, которое motionManager отправляет в нее. Я проверил документацию на startAccelerometerUpdatesToQueue, но там не говорится, что получатель сохраняет очередь, так что это, вероятно, не то, что вы можете смело предположить. Мое предложение - не выпускать очередь автоматически. Вместо этого отпустите его в viewDidUnload после вызова stopAccelerometerUpdates в motionManager.

...