私は加速度計(毎秒20サンプル)から読み込み、タイマーを使用して5秒ごとにこれらのデータを取り込み、計算します。 加速度計データはプロパティであるNSMutableArray(加速度)に保存されます。次に、タイマーがトリガされると、この配列はセマフォを使用して新しいものにコピーされます(計算が完了している間に新しいデータを保存するため)。ブロックからの@autoreleasepoolのEXC_BAD_ACCESS
main.mの@autoreleasepool返信文にEXC_BAD_ACCESSが表示されます(変更はありません)。私はこのエラーは、私はアプリを実行するたびに同じ瞬間ではありません:それはタイマーブロックの実行のいずれかに表示されますが、特定の時間(時には2回目、時には5回目など)には表示されません非常に困惑した。
私はそれを解決するために数日間メモリ管理について調べて読んでいますが、私はそれをしません。ブロックに変数を使うのは間違いだと思いますが、わかりません。
誰かが被写体にどんな光を当てても大変感謝しています。
関連するコードはここにある:
/**
* Function to create the timer
**/
dispatch_source_t creaTimer(uint64_t interval,uint64_t leeway, dispatch_queue_t queue,dispatch_block_t block){
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0,queue);
if (timer) {
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
}
return timer;
}
/**
* IBAction which executes when an "Start" button is tapped
**/
-(IBAction) rec{
semaforoArrays = dispatch_semaphore_create(1); //creates semaphore to accessing the saved accelerometer data
__block double *modulos;
modulos = (double *) malloc(512);
__block DOUBLE_COMPLEX_SPLIT A;
/* Allocate memory for the input operands and check its availability,
* use the vector version to get 16-byte alignment. */
A.realp = (double *) malloc(1024 * sizeof(double));
A.imagp = (double *) malloc(1024 * sizeof(double));
if (A.realp == NULL || A.imagp == NULL) {
printf("\nmalloc failed to allocate memory for the real FFT"
"section of the sample.\n");
exit(0);
}
timer = creaTimer(5ull * NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)
,^{
if(numCiclos>0){
dispatch_semaphore_wait(semaforoArrays, DISPATCH_TIME_FOREVER);
NSMutableArray *originalArray= [NSMutableArray arrayWithArray:
self.aceleraciones]; //copy the saved data to manipulate them
[self.aceleraciones removeAllObjects]; //remove the saved data to put into the array the new data accelerometer will have
dispatch_semaphore_signal(semaforoArrays);
int tamanno=[originalArray count];
for(int h=0;h<1024;h++){
A.realp[h]=0;
A.imagp[h]=0;
} //i reuse the same array (to avoiding allocating it each time)
for(int r=0;r<tamanno;r++){
A.realp[r]=[[originalArray objectAtIndex:r]doubleValue];
} //i do that to calculate the Fourier Transform but it doesn´t
matter in the error (i get it also with this code).
vDSP_zvabsD(&A, 1, modulos, 1, 512);
vDSP_vsqD(modulos,1,modulos,1,512);
double sum=0;
vDSP_sveD(modulos, 1, &sum, 512);
sum=sum/2.0;
vDSP_vsdivD(modulos, 1, &sum, modulos, 1, 512);
}
numCiclos++;//variable to avoid the execution of the block the first time timer triggers (when it is started)
});
//until here is the problematic block. I'm sure the error is before this line.
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
if (motionManager.accelerometerAvailable) {
motionManager.accelerometerUpdateInterval = 1.0/20.0;
label.text = [NSString stringWithFormat:@"Registrando"];
[motionManager startAccelerometerUpdatesToQueue:queue withHandler:
^(CMAccelerometerData *accelerometerData, NSError *error){
if (error) {
[motionManager stopAccelerometerUpdates];
label.text = [NSString stringWithFormat:
@"Error en el acelerometro: %@", error];
}
else{
if(primeraLectura){
primeraLectura = FALSE;
dispatch_resume(timer); //starts timer
}
dispatch_semaphore_wait(semaforoArrays, DISPATCH_TIME_FOREVER);
[self.aceleraciones addObject:[NSNumber numberWithDouble:
sqrt(accelerometerData.acceleration.x*accelerometerData.acceleration.x+
accelerometerData.acceleration.y*accelerometerData.acceleration.y+
accelerometerData.acceleration.z*accelerometerData.acceleration.z)]];
//it saves the acceleration module
dispatch_semaphore_signal(semaforoArrays);
}
}];
}else{
label.text = @"Este dispositivo no tiene acelerometro.";
}
}
手動保持/解放またはARCを使用していますか?前者の場合は、間違いなく何かをリリースしてはいけません。何でもかまいません - あなたが最近変更したコードに必ずしもあるとは限りません。 –
@ホットリック私は手動メモリ管理を使用していますが、ブロック内の計算に関する行を削除しても、実行時に問題はありません。 – angeleke
昨日、私はすべてのリファレンスでオブジェクトを再作成するのをやめ、代わりにキャッシュしました。これはあなたが見ているのとまったく同じエラーを引き起こしました。しかし、バグ(私が最終的にそれを見つけたとき)は、私の変更のどれにもなく、オブジェクトを埋め込むコードにありました.1つのアイテムが過剰にリリースされました。以前は、オブジェクトはバグが公開されるのに十分長くは住んでいなかった。 –