我正在編寫代碼來渲染和旋轉其細節正在被同時計算和更新的圖片。它在單線程(帶有顯示鏈接)上無錯誤地工作,但看起來很笨重,我不希望計算被顯示鏈接觸發。所以我想在主線程(顯示鏈接)中執行所有與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