0

在我的应用程序中,我正在做一些音频处理。在音频缓冲区的 for 循环中,有一个 NSMutable 数组。该循环每秒被调用很多次(取决于缓冲区大小)。举个例子 :

@autoreleasepool
{
    for ( int i = 0; i < tempBuffer.mDataByteSize / 2; ++i )
    {
        if ( samples[i] > trig)
        {
            [self.k_Array addObject:[NSNumber numberWithInt:k]];

            // other stuff

        }
    }
}

然后,每一秒,我都会调用一个函数进行其他处理。

- (void)realtimeUpdate:(NSTimer*)theTimer
{
// Create a copy of the array
NSMutableArray *k_ArrayCopy = [NSMutableArray arrayWithArray:k_Array]; // CRASH with EXC_BAD_ACCESS code 1 error

//do some stuff with k_ArrayCopy
}

我有时会收到 EXC_BAD_ACCESS 错误,因为我认为是数组的锁定问题。我花了很多时间试图获取有关队列、锁定、工作副本等的信息……但我对这个特定情况感到迷茫。我的问题:

  1. 我必须使用原子还是非原子k_array
  2. 我必须使用dispatch_sync功能吗?如果是这样,具体在哪里?
  3. 应该realtimeUpdate在后台调用该函数吗?

提前致谢 !

4

1 回答 1

0

使用可以解决问题的调度队列

//创建队列实例变量

dispatch_queue_t q = dispatch_queue_create("com.safearrayaccess.samplequeue", NULL);

//1.

 @autoreleasepool
    {
        for ( int i = 0; i < tempBuffer.mDataByteSize / 2; ++i )
        {
            if ( samples[i] > trig)
            {
               dispatch_async(q, ^{ 
                //queue block
                [self.k_Array addObject:[NSNumber numberWithInt:k]];

                });

                // other stuff NOTE: if its operation on array do it in queue block only

            }
        }
    }

//2。

 - (void)realtimeUpdate:(NSTimer*)theTimer
  {
    // Create a copy of the array
    __block NSMutableArray *k_ArrayCopy;//when you use any variable inside block add __block before it

    dispatch_async(q, ^{
            //queue block
            k_ArrayCopy = [NSMutableArray arrayWithArray:k_Array]; 
        });

        //do some stuff with k_ArrayCopy
    }

现在您的添加和读取数组操作在同一个队列中并且不会冲突。有关使用调度队列的更多详细信息,请通过苹果 Grand Central Dispatch doc

其他方法是使用 NSConditonLock

于 2013-10-23T21:07:31.890 回答