Проблемы Objective-C с потоками и потоками? - PullRequest
1 голос
/ 13 октября 2011

Я действительно не знаю наверняка, что это проблема с потоками, но я не знаю, что еще может быть причиной моих проблем.У меня есть приложение для iOS с NSStreamDelegate, вызывающим

- (void) stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode

. Делегат получает дескриптор для AppDelegate, и в любой другой части StreamDelegate существует AppDelegate.Однако в потоке: handleEvent: при попытке передать результаты обратно в AppDelegate для дополнительной обработки я получаю сообщение об ошибке EXC_BAD_ACCESS.

Единственная причина, по которой я думаю, что это может быть проблема с многопоточностью, заключается в том, что документацияon stream: handleEvent: states:

Делегат получает это сообщение только в том случае, если поток Stream запланирован в цикле выполнения.Сообщение отправляется в потоке объекта потока.Делегат должен проверить streamEvent, чтобы определить соответствующее действие, которое он должен предпринять.

Имеет ли «поток объекта потока» ссылку на мой StreamDelegate?Или это ссылка на поток, передаваемый в метод?Я предполагаю позже, но хочу убедиться, что я не ошибаюсь.

Если это иная нить, чем та, на которой сидит мой AppDelegate, то это то, что вызывает моюпроблемы?Если так, то как мне справиться с этим?

Редактировать : за @bbum, я обновляюсь, чтобы указать, что я сделал.

После взлома,Я попробовал кое-что, что я рассмотрел и затем отклонил.По сути, я создал фиктивный класс, который создается и вызывается из stream: handleEvent :.Я вызываю метод, который работает с:

[man performSelectorOnMainThread:@selector(saveEvent:) withObject:jsonDict waitUntilDone:YES];

Внутри saveEvent:, я перезваниваю в AppDelegate и (почти!) Все работает с этого момента.

В настоящее время у меня проблема с отладчиком, который жалуется на попытку записи в файл, который не существует.Я пока не знаю, почему это так.Имя файла выглядит подозрительно, как хешированный каталог, который создается для приложения под «iPhone Simulator / 5.0 / Applications /», но я не выяснил, где именно происходит ошибка.

ДействительноЗапутанная часть этого в том, что я просто не могу получить трассировку стека при любых сбоях.Я пытался использовать LLVM 3.0 и LLVM GCC 4.2 с соответствующими отладчиками, но ничего.Я использую Xcode 4.2.У меня не было этой проблемы с 4.1.

Спасибо за слова мудрости, @bbum.Очень признателен.Я выложу еще одно обновление, как только получу это полностью.

Редактировать (2011-10-18): [Обновление: неважно;Я идиот.Я читал поток в байтовом массиве, но не объявлял явный размер.Я столкнулся с каким-то переполнением буфера.Теперь все работает.]

Я уже несколько дней бью головой об стену, а затем переписываю код из-за вышеуказанных ошибок.Я снова почти на грани того, чтобы все заработало, но поток все еще, кажется, кусает меня в заднице.

Я получаю следующую ошибку:

предупреждение: Невозможно восстановить ранее выбранный кадр.

Я получаю данные в NSInputStream и записываю их, а затем пытаюсь обновить представление, чтобы указать обновление.В какой-то момент после того, как звонки сделаны, я должен увидеть вызов viewWillAppear: (BOOL) анимированный, но сначала появляется предупреждение выше, и приложение блокируется.

Я много гуглил на вышеупомянутоми обычно ошибка возникает, когда есть какой-то бесконечный цикл, переполнение стека или что-то, что забивает память.Я не вижу ничего подобного.Я все еще думаю, что сталкиваюсь с проблемой, когда мои потоки пересечены, и стек становится запутанным.Я просто не могу понять, почему.

Вызываемый выше селектор saveEvent: делает свое дело, а затем изменяет свойство в представлении, указывая, что оно грязное.Это свойство трогается.Я вижу, как это происходит, когда я ставлю перерыв.Но viewWillAppear: никогда не вызывается.

Это было до смешного разочарование. Это кажется такой простой вещью, но какой это был беспорядок.

Ответы [ 2 ]

1 голос
/ 14 октября 2011

Относится ли "поток объекта потока" к моему StreamDelegate?Или это ссылка на поток, передаваемый в метод?Я предполагаю позже, но хочу убедиться, что я не ошибаюсь.

В каждом потоке может быть только один runloop.Делегат будет вызываться в любом потоке, в котором находится поток выполнения, на который запланирован поток.

Если это поток, отличный от того, в котором находится мой AppDelegate, то это то, что вызывает мои проблемы?Если так, то как мне с этим справиться?

Скорее всего;если ваш AppDelegate не является потокобезопасным, и поток запланирован в неосновном потоке, то вполне вероятно, что это проблема.

Без дополнительной информации невозможно сказать больше.Поскольку приложение аварийно завершает работу, вы должны как минимум опубликовать обратную трассировку.

0 голосов
/ 27 октября 2011

Вы решили это? Я делаю что-то очень похожее, и у меня это работает, хотя я сталкиваюсь с проблемой случайного получения не всех символов, которые должны появляться в потоке.

Если это поможет, я могу опубликовать код, который работает в моей ситуации.

По сути, мой код запускает фоновый поток, который делегат затем использует для мониторинга потока.

-(void)backgroundThreadFunction:(NSObject*)obj
{
    [self setBackgroundThread:[NSThread currentThread]];
    [streamDelegate OpenSession:accessoryInfo];

    while(_continueRunning) {
        NSAutoReleasePool *_pool = [[NSAutoReleasePool alloc] init];
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];
        [_pool release];
    }

    [self setBackgroundThread:nil];
}

И делегат Stream OpenSession указывает на выполнение в текущем потоке следующим образом.

[[currentSession inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[[currenSession outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Когда я хочу, чтобы appDelegate что-то знал, я обычно использую NSNotification, который был зарегистрирован для этого события.

[[NSNotificationCenter defaultCenter] postNotificationName:@"DataReceived" object:_receivedData];

Надеюсь, это поможет.

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...