Почему я не использую NSLock?

Я пишу код для рендеринга и поворота изображения, детали которого одновременно вычисляются и обновляются. Он работает без ошибок в одном потоке (с ссылкой на изображение), но выглядит неуклюжим, и я не хочу, чтобы вычисления запускались по ссылке дисплея. Поэтому я хочу выполнить весь код, связанный с OpenGL, в основном потоке (с помощью ссылки на изображение) и все вычисления во втором потоке (выполнение цикла while (YES)).

Я реализовал это с помощью 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]; } ... 

Благодаря!

One Solution collect form web for “Почему я не использую NSLock?”

Я думаю, что в этом случае вам будет гораздо легче использовать грандиозную центральную отправку.

 @interface MyController : NSObject { // Not use why you're not inheriting from NSController here. dispatch_queue_t calQueue; ... } - (void) awakeFromNib { calcQueue = dispatch_queue_create("com.yourApp.calc", DISPATCH_QUEUE_SERIAL); dispatch_async(calcQueue, ^{ while(YES) // This will peg the CPU at 100% [myModel calculate]; }); } 

модельный класс

 @interface MyModel : NSObject { dispatch_queue_t modelQueue; ... } @property dispatch_queue_t modelQueue; @implementation myModel -(id) init { modelQueue = dispatch_queue_create("com.yourApp.model", DISPATCH_QUEUE_SERIAL); } -(void) dealloc { dispatch_release(modelQueue); } -(void) changeModelAppearance { dispatch_async(modelQueue, ^{ ... }); } ... 

Посмотреть

 @implementation MyView -(void) modelUpdated:(NSNotification *) notification { // modelUpdated is called via the NSNotificationCenter MyModel* myModel = (MyModel*) [notification object]; dispatch_async(model.modelQueue, ^{ ... // update OpenGL structures with data from myModel }); } ... 

Чтобы приостановить любую из очередей, вы просто вызываете dispatch_suspend и для перезапуска любой очереди используйте dispatch_resume

Если вы используете таймер вместо бесконечного цикла, вы можете уменьшить количество используемого вами процессора.

 calcTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); dispatch_source_set_timer(calcTimer, DISPATCH_TIME_NOW, DT, 1000); dispatch_source_set_event_handler(calcTimer, ^{ ... }); dispatch_resume(calcTimer); 

Это потребует гораздо более низких затрат на процессор.

  • Как зашифровать или обфускать объектный код c?
  • Как локализовать раскадровку iOS
  • Ошибка анимации UITableViewCell в `moveRowAtIndexPath: toIndexPath:` при использовании `ratedRowHeight` и` UITableViewAutomaticDimension`
  • Применение тени к массиву UIImageView
  • Xcode удаление языковых расписаний iOS
  • Как добавить `accessibilityLabel` в` UIAlertView` кнопки?
  • Маскировка изменяет цвета UIImage-iOS
  • DelayTime или UnclampedDelayTime для GIFS
  • AVMetadataFaceObject Precision
  • Вставить текст в UILabel
  • Почему UIView: animateWithDuration завершается немедленно?
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.