我正在编写代码来渲染和旋转其细节正在被同时计算和更新的图片。它在单线程(带有显示链接)上无错误地工作,但看起来很笨重,我不希望计算被显示链接触发。所以我想在主线程(显示链接)中执行所有与OpenGL相关的代码,并在第二个线程中执行所有计算(执行一段时间(YES)循环)。为什么我不使用NSLock工作?
我使用NSThread实现了这一点。它在一段时间内效果很好,然后在glDrawArrays过程中出现'线程1:程序接收信号:“EXC_BAD_ACCESS”',并且有时会出现奇怪的闪烁图形。这是我期望的,如果主线程在第二个线程覆盖它的同时读取模型级数据。
然后,我在模型对象中定义了一个NSLock,并将其锁定(在我的模型类中)和阅读(在我的视图类中)...但它仍然会导致相同的错误,并且图形仍然偶尔会有奇怪的闪光。
我在这里做错了什么,或者是我的问题在别的地方?
其次,在这种情况下停止第二个线程的正确方法是什么? NSThread类参考建议使用cancel,检查isCancelled,如果存在则退出,但它也表示应该避免调用退出。
下面是修改代码 - 在我的控制器类(我使用的XCode 4.2与ARC;我所有的ivars都非原子):
@interface MyController : NSObject {
NSThread *calcThread;
...
}
// (I do not give it an @property or @synthesize line)
@implementation MyController
- (void) awakeFromNib {
calcThread = [[NSThread alloc] initWithTarget:self
selector:@selector(calcLoop:) object:nil];
[calcThread start];
...
}
- (void) calcLoop:(id)arg {
@autoreleasepool {
while (YES)
[myModel calculate];
}
}
...
我把NSLock在我的模型类:
@interface MyModel : NSObject {
NSLock* oLock;
...
}
@property (nonatomic, strong) NSLock* oLock;
@implementation myModel
-(id) init {
oLock = [[NSLock alloc] init];
...
}
-(void) changeModelAppearance {
[oLock lock];
...
[oLock unlock];
}
...
在我看来类:
@implementation MyView
-(void) modelUpdated:(NSNotification *) notification {
// modelUpdated is called via the NSNotificationCenter
MyModel* myModel = (MyModel*) [notification object];
[myModel.oLock lock];
... // update OpenGL structures with data from myModel
[myModel.oLock unlock];
}
...
谢谢!
你在哪里调用'glDrawArrays'? – 2011-12-27 11:10:11
对'glDrawArrays'的调用在视图类中,在另一个方法中('render');它根本不涉及模型。 – 2011-12-27 21:25:43
我意识到我的代码有一个问题,'modelUpdated'方法可能会在调用'render'方法的同时更新OpenGL结构,因为NSNotificationCentre可以从任何线程调用它。所以我现在在modelUpdated中插入了第二个锁,并将它放在'glDrawArrays'的render方法中。但我仍然得到同样的错误。 – 2012-01-02 05:47:13