簡體   English   中英

@autoreleasepool中的EXC_BAD_ACCESS來自一個塊

[英]EXC_BAD_ACCESS in @autoreleasepool from a block

我正在開發一個從加速度計讀取的應用程序(每秒20個樣本),並使用計時器,每5秒獲取一次這些數據並進行計算。 加速度計數據保存在一個屬性NSMutableArray(aceleraciones)中。 然后,當計時器觸發時,使用信號量將該數組復制到一個新數組(以便在完成計算時保存新數據)。

我在main.m的@autoreleasepool返回語句中得到一個EXC_BAD_ACCESS(我在那里沒有做任何更改)。 我每次運行應用程序時都會出現此錯誤,但不是在同一時間運行:它出現在一個計時器塊執行中,但沒有在特定時間(有時在第二次,有時在第五次,依此類推)中出現,所以我很困惑。
為了解決這個問題,我幾天來一直在搜索和閱讀有關內存管理的信息,但我不願意這樣做。 我猜這是關於在塊中使用變量的錯誤,但是我不確定。

如果有人可以對這個問題提出任何建議,我將不勝感激。

相關代碼在這里:

/**
* 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.";
}
}

調試這些錯誤的最佳方法是在Instruments中。 使用Zombie配置文件運行,並在執行導致訪問錯誤的代碼時,將彈出一個窗口。 單擊右下角的箭頭以查看alloc / dealloc列表,一行將顯示有問題的代碼。

motionManager startAccelerometerUpdatesToQueue:查看motionManager startAccelerometerUpdatesToQueue: 您很可能將queue參數保存在該屬性中,然后在dealloc釋放它。 但是,當您將queue值放入屬性中時,並沒有保留它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM