Я пишу код для рендеринга и поворота изображения, детали которого одновременно вычисляются и обновляются. Он работает без ошибок в одном потоке (с ссылкой на изображение), но выглядит неуклюжим, и я не хочу, чтобы вычисления запускались по ссылке дисплея. Поэтому я хочу выполнить весь код, связанный с OpenGL, в основном потоке (с помощью ссылки на изображение) и все вычисления во втором потоке (выполнение цикла while (YES)).Почему я не использую NSLock?
Я реализовал это с помощью NSThread. Он работает красиво некоторое время, а затем не работает с «Thread 1: Program received signal:« EXC_BAD_ACCESS »во время glDrawArrays и иногда имеет странные вспышки графики. Это то, что я ожидал, если основной поток читает данные на уровне модели, в то время как второй поток переписывал его.
Затем я определил NSLock в объекте модели и заблокировал его для всех записей (в моем классе модели) и чтения (в моем классе вида) ... но он все равно может привести к той же ошибке, а графика все еще иногда странные вспышки.
Я сделал что-то неправильно здесь, или это моя проблема в другом месте?
Во-вторых, что является правильным способом остановить второй поток в этом случае? Ссылка на класс NSThread предполагает использование отмены, проверка isCancelled и выход из нее, но это также говорит о том, что следует избегать выхода из вызова.
Вот модификации коды - в моем классе контроллера (я использую XCode 4.2 с ARC, все мои Ивары являются неатомическими):
@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'? –
Вызов 'glDrawArrays' находится в классе представления, в другом методе (' render'); он вообще не относится к модели. –
Я понял, что одна проблема с моим кодом заключается в том, что метод modelUpdated может обновлять структуры OpenGL, в то же время вызывается метод render, поскольку NSNotificationCentre может вызывать его из любого потока. Поэтому теперь я вставил вторую блокировку в modelUpdated, а также поместил ее в метод визуализации вокруг 'glDrawArrays'. Но я все равно получаю ту же ошибку. –