我找不到任何示例如何在使用操作队列时处理相同(类)变量。在 C 和线程中,它是关于互斥锁的。那么,当NSOperationQueue
启动一个线程进行操作,类变量被修改时会发生什么呢?它是线程安全的吗?谢谢。
@interface MyTest {
NSMutableArray *_array;
}
@end
-(id)init
{
...
_array = [NSMutableArray new]; // class variable
// queue time consuming loading
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation =
[NSInvocationOperation initWithTarget:self
selector:@selector(populate)
object:nil];
[queue addOperation:operation];
// start continuous processing
[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(processing)
userInfo:nil
repeats:YES];
...
}
-(void)populate
{
while (...)
{
id element = ...; // time consuming
// modify class variable "_array" from operation's thread (?)
[_array addObject:element];
// Ok, I can do instead of addObject
// performSelectorOnMainThread:withObject:waitUntilDone:
// but is it the only way? Is it needed?
}
}
// access and/or modify class variable "_array"
-(void)processing
{
NSLog(@"array.count = %d", array.count);
for (id i in _array)
{
[_array addObject:[NSNumber numberWithInt:rand() % 100]];
// etc...
}
}
最佳答案
不,这不是线程安全的,如果你启动一个线程对一个可以被其他线程修改的类变量做一些工作,那么它不是线程安全的,如果在 populate 运行时从某个线程调用处理另一个然后当 foreach 循环看到数组已被修改时你可能会得到一个异常,尽管你在你的例子中修改 foreach 循环内的数组时无论如何你都会得到那个异常(你不应该这样做,并且程序将抛出一个异常)...解决这个问题的一种方法是在数组上使用同步块(synchronized block),它将确保同步块(synchronized block)不会同时执行,线程阻塞直到一个同步块(synchronized block)完成,例如
-(void)populate
{
while (...)
{
id element = ...; // time consuming
// modify class variable "_array" from operation's thread (?)
@synchronized(_array)
{
[_array addObject:element];
} // Ok, I can do instead of addObject
// performSelectorOnMainThread:withObject:waitUntilDone:
// but is it the only way? Is it needed?
}
}
// access and/or modify class variable "_array"
-(void)processing
{
@synchronized(_array)
{
NSLog(@"array.count = %d", array.count);
for (id i in _array)
{
//you shouldnt modify the _array here you will get an exception
// etc...
}
}
}
关于iphone - 线程安全 : NSOperationQueue + [array addObject],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8597832/