Синхронизация проблем NSMutableData - PullRequest
1 голос
/ 21 сентября 2011

У нас есть объект NSMutableData, к которому часто добавляются данные.Мы также часто извлекаем данные с помощью метода bytes для чтения.

Мы синхронизировали доступ к этому объекту NSMutableData через мьютекс pthread:

pthread_mutex_t _mutex;

pthread_mutexattr_t attributes;
pthread_mutexattr_settype( &attributes, PTHREAD_MUTEX_DEFAULT );
pthread_mutex_init( &_mutex, &attributes );

, а затем каждый раз, когда получаем доступэтот объект мы:

pthread_mutex_lock(&_mutex);
const UInt8* rawData = [_coverage bytes];
//code that works with the raw bytes
pthread_mutex_unlock(&_mutex);

Кроме того, каждый наш addData метод блокирует мьютекс перед добавлением данных в объект NSMutableData.

Проблема в том, что мы все еще получаем случайный EXC_BAD_ACCESSво время работы с rawData.Я понимаю, что NSMutableBytes будет увеличивать свой байтовый массив по мере добавления к нему данных.Я также понимаю, что не должен ожидать магического роста rawData.

Мне просто интересно, как мы можем попасть в такую ​​ситуацию, когда rawData был свободен из-под нас, когда мыявно заблокировали доступ как для чтения, так и для записи?

Что-то не так с мьютексом или с доступом к байту?

РЕДАКТИРОВАТЬ

Я обнаружил настоящую причину, почему я получал EXC_BAD_ACCESS.Я не инициализировал атрибуты мьютекса, поэтому блокировка мьютекса ничего не сделала.Вот исправленный код:

pthread_mutex_t _mutex;

pthread_mutexattr_t attributes;
pthread_mutexattr_init(&attributes);
pthread_mutex_init(&_mutex, &attributes);
pthread_mutexattr_destroy(&attributes);

1 Ответ

1 голос
/ 21 сентября 2011

Да, возможно, это освобождается из-под вас.

Согласно документации :

байт Возвращает указатель на содержимое получателя.

Вы должны сделать копии данных, чтобы гарантировать, что они не будут изменены или освобождены из-под вас.Когда вы закончите с вашей копией, убедитесь, что free() это.

pthread_mutex_lock(&_mutex);
const UInt8 *origData = [_coverage bytes];
UInt8 *rawData;
memmove(rawData, origData, [_coverage length]);

//code that works with the raw bytes
free(rawData);
pthread_mutex_unlock(&_mutex);
...