- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我有两个不同的线程通过 GCD 访问 NSMutableArray
一个线程只是根据可变数组创建一个新数组,而另一个线程正在从数组中删除记录,我应该认为这是一个问题吗?也就是说,我认为副本只是“读取”数组,难道不应该只获取当时数组中的任何内容吗?我没有枚举任一线程中的数组,但它仍然崩溃。一旦我删除读取例程,它就可以正常工作。
这里是“阅读”:
dispatch_async(saveQueue, ^{
NSDictionary*tempstocks=[NSDictionary dictionaryWithDictionary:self.data];
它在此线程上崩溃:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[9]'
这是另一个线程上发生的事情:
[self.data removeObjectForKey:item];
我知道你不能在枚举时进行变异,但我认为在变异时阅读是可以的,你可能不知道你得到的是哪个版本的变异对象,但我不认为这是一个问题,但是显然是的。也许dictionaryWithDictionary
方法正在执行一个首先看到 X 个对象的操作,但当例程完成时,它包含 X-Y 对象,因此它没有“捕获”整个 self.data
运行时一下子就能字典 dictionaryWithDictionary
而是枚举 self.data
这本质上与枚举时的变异问题相同?
最佳答案
我猜你可能会使用 GCD 创建三个不同的队列:一个用于保存,第二个用于其他操作,最后一个用于使用 NSMutableArray
进行操作。
dispatch_async(saveQueue, ^{
dispatch_barrier_async(_queue, ^{
NSDictionary*tempstocks=[NSDictionary dictionaryWithDictionary:self.data];
});
});
dispatch_async(anotherQueue, ^{
dispatch_barrier_async(_queue, ^{
[self.data removeObjectForKey:item];
});
});
它类似于@synchronize
,但使用GCD。
更多信息:GCD Reference/dispatch_barrier_async和 http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html
编辑
我做了一些性能测试,以便了解哪种方式更快:
- (void)usingSynchronized
{
dispatch_queue_t writeQyeue = dispatch_queue_create("com.tikhop.writeQyeue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(writeQyeue, ^{
for(size_t i=0; i<10000; i++)
@synchronized (arr) {
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:1]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:2]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:3]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:4]];
}
});
}
- (void)usingGCD
{
dispatch_queue_t writeQyeue = dispatch_queue_create("com.tikhop.writeQyeue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(writeQyeue, ^{
for(size_t i=0; i<10000; i++)
dispatch_barrier_async(_queue, ^{
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:5]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:6]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:7]];
[arr replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:8]];
});
});
}
arr = [NSMutableArray arrayWithCapacity:1];
[arr addObject:@(0)];
[self usingSynchronized];
[self usingGCD];
我得到了以下结果:
关于cocoa - 读取时改变数组,而不是枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11920584/
我是一名优秀的程序员,十分优秀!