Почему я не использую 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); 

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

  • Автоматическая блокировка iPhone программно
  • Получение внутренней ошибки 500 с использованием MKNetworking Загрузка изображения PHP
  • Предварительная фотография AVCaptureSession и размер AVCaptureVideoPreviewLayer
  • Как добавить URL-адрес в список чтения Safari в iOS?
  • supportInterfaceOrientations не вызывается с iOS 7
  • Почему инициализация UITableViewCell не работает внутри initWithCoder
  • Анимация UIView внутри UITableViewCell
  • UIView animateWithDuration: продолжительность: анимация: завершение: похоже, есть переход по умолчанию?
  • Как рисовать звезды с помощью кварцевого ядра?
  • Objective-C: сравнение изображения с другим ранее сохраненным изображением
  • XCode: Показать все локализованные файлы для одного языка (проект IOS)
  • Interesting Posts

    Контроллер панели вкладок в iPhone

    Как обнаружить событие касания в детском контролере просмотра в ios

    Сравнение дат месяца с массивом

    Настройка панели навигации ABPeoplePickerNavigationController в iOS 8

    Построение списка NSS-нисходящих строк в виде NSString *

    Как получить контакты с электронной почтой из адресной книги в iOS?

    Невозможно изменить камеруFlashMode для UIImagePickerController

    Хороший подход для нескольких контроллеров подробного просмотра для навигационных проектов

    Странная проблема из-за поддержки блоков для iOS 3.1.3

    Ошибка iOS – EXC_BAD_ACCESS

    Каков возможный способ создания игровой графики для Corona SDK?

    ios изменить блокировку экрана тип уведомления форма баннер для типа оповещения

    Изменение устройства захвата камеры во время записи видео

    Способ получения возвращаемого типа метода в Objective C?

    NSClassFromString () всегда возвращает nil

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.