2011-09-21 193 views
1

我们有一个经常附加数据的NSMutableData对象。我们还经常通过bytes方法提取数据进行阅读。同步NSMutableData问题

我们通过并行线程同步互斥访问该NSMutableData对象:

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对象之前的互斥体。

问题是我们仍然在rawData处得到偶尔EXC_BAD_ACCESS。我知道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

是的,它可能是从你下面被释放。

按照documentation

字节
返回一个指针接收器的内容。

您应该制作数据副本以确保它不会被更改或从下面释放。当你完成你的副本确保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); 
+0

每次只通过公共API访问字节还是更好地管理自己的字节数组更好? –

+0

这实际上取决于它如何使用,因为NSMutableData使附加数据变得容易很多。正如你所说,这个互斥体本身并不起作用似乎很奇怪,但如果在那个互斥体之外的某个地方改变了可能成为问题的数据。您没有发布追加操作,请仔细检查并确保其正确锁定。 – Joe