나는 세부 사항이 동시에 계산되고 업데이트되는 그림을 렌더링하고 회전하는 코드를 작성 중입니다. 단일 스레드 (디스플레이 링크 포함)에서 오류없이 작동하지만보기 흉한 것처럼 보입니다. 디스플레이 링크에 의해 계산이 시작되는 것을 원하지 않습니다. 그래서 메인 링크의 모든 OpenGL 관련 코드 (디스플레이 링크 포함)와 두 번째 스레드의 모든 계산 (while (YES) 루프 실행)을 실행하려고합니다.NSLock을 사용하지 않는 이유는 무엇입니까?
NSThread를 사용하여 구현했습니다. 그것은 아름답게 잠시 작동하고 glDrawArrays 중에 '스레드 1 : 프로그램 수신 신호 : EXC_BAD_ACCESS' '가 실패하고 때로는 이상한 그래픽이 깜박입니다. 이것은 주 스레드가 두 번째 스레드가 모델 레벨 데이터를 덮어 쓰는 동시에이 스레드를 읽으면 예상했던 것입니다.
그런 다음 모델 객체에 NSLock을 정의하고 내 모델 클래스의 모든 쓰기 및 내 뷰 클래스의 읽기를 위해 잠 갔지만 여전히 같은 오류가 발생할 수 있으며 그래픽은 여전히 때로는 이상한 플래시가 있습니다.
내가 여기 뭔가 잘못되었거나 다른 곳에서 문제가 있습니까?
둘째,이 경우 두 번째 스레드를 중지하는 올바른 방법은 무엇입니까? NSThread 클래스 참조는 취소, isCancelled 확인 및 종료를 제안하지만 exit 호출은 피해야합니다. 여기
코드에 대한 수정입니다 - 내 컨트롤러 클래스 (나는 ARC와 엑스 코드 4.2을 사용하고, 내 모든 인스턴스 변수 비 원자이다) :@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')에서 뷰 클래스에 있습니다; 그것은 모델을 전혀 언급하지 않습니다. –
NSNotificationCentre가 어떤 스레드에서든 호출 할 수 있기 때문에'modelUpdated' 메소드가'render' 메소드가 호출되는 동시에 OpenGL 구조체를 업데이트 할 수 있다는 것이 내 코드의 문제점 중 하나임을 깨달았습니다. 이제 modelUpdated에 두 번째 잠금을 삽입하고'glDrawArrays' 주위의 render 메소드에 넣습니다. 하지만 여전히 같은 오류가 발생합니다. –