2013-07-28 4 views
0

Я создал механизм соединения сокета в iOS. Он работает достаточно хорошо. Но время от времени (около 1%) он рушится. Здесь это журнал сбоев, есть ли у вас какие-либо идеи, почему это происходит.Сбой соединения сокета iOS

Thread 0 Crashed: 
0 libobjc.A.dylib      0x3b01b5b0 _objc_msgSend + 16 
1 CoreFoundation      0x332957cf _signalEventSync + 75 
2 CoreFoundation      0x3329b623 _cfstream_solo_signalEventSync + 75 
3 CoreFoundation      0x33295507 _CFStreamSignalEvent + 327 
4 CFNetwork       0x32ffa6ff CoreWriteStreamCFStreamSupport::coreStreamWriteEvent(__CoreWriteStream*, unsigned long) + 99 
5 CFNetwork       0x32ffa0b5 CoreWriteStreamClient::coreStreamEventsAvailable(unsigned long) + 37 
6 CFNetwork       0x32ffb365 CoreStreamBase::_callClientNow() + 45 
7 CFNetwork       0x32ffb0f9 CoreStreamBase::_streamSetEventAndScheduleDelivery(unsigned long, unsigned char) + 89 
8 CFNetwork       0x32ffb4ff CoreStreamBase::_streamInterface_SignalEvent(unsigned long, CFStreamError const*) + 35 
9 CFNetwork       0x32f69b57 SocketStream::socketCallback(__CFSocket*, unsigned long, __CFData const*, void const*) + 135 
10 CFNetwork       0x32f69ab3 SocketStream::_SocketCallBack_stream(__CFSocket*, unsigned long, __CFData const*, void const*, void*) + 75 
11 CoreFoundation      0x332cfd81 __CFSocketPerformV0 + 385 
12 CoreFoundation      0x332cd683 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 
13 CoreFoundation      0x332ccf7f __CFRunLoopDoSources0 + 363 
14 CoreFoundation      0x332cbcb7 __CFRunLoopRun + 647 
15 CoreFoundation      0x3323eebd _CFRunLoopRunSpecific + 357 
16 CoreFoundation      0x3323ed49 _CFRunLoopRunInMode + 105 
17 GraphicsServices     0x36e172eb _GSEventRunModal + 75 
18 UIKit        0x35154301 _UIApplicationMain + 1121 
19 Okey101Plus       0x000e19ab main (main.m:16) 
+0

Я столкнулся точно в том же стеке. Я устанавливаю делегат назначения нулем при закрытии сокета (также в dealloc), любой ключ? Как вы избавились от этого? –

ответ

1

Я на самом деле не совсем уверен, но, основываясь на отчете, похоже, писать на сокет не удается -

CoreWriteStreamCFStreamSupport::coreStreamWriteEvent(__CoreWriteStream*, unsigned long) + 99 

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

От компании Apple Docs: Во многих сетевых приложениях, сетевые ошибки могут возникнуть, которые не имеют никакого отношения к вашему приложению (Вероятно, они имели в виду здесь, например:. Вы можете получить чтение ошибки сокета, если интерфейс становится недоступным, когда сетевое соединение теряется). Однако большинство пользователей, вероятно, не знают, почему приложение терпит неудачу. API CFNetDiagnostics позволяет вам быстро и легко помочь пользователю исправить свои сетевые проблемы, приложив немного усилий.

Чтобы диагностировать проблему с помощью помощника по диагностике сети, вызовите функцию CFNetDiagnosticDiagnoseProblemInteractively и передайте сетевую диагностическую ссылку. В листинге 6-1 показано, как использовать CFNetDiagnostics с потоками, реализованными в цикле выполнения.

case kCFStreamEventErrorOccurred: 
     CFNetDiagnosticRef diagRef = 
      CFNetDiagnosticCreateWithStreams(NULL, stream, NULL); 
     (void)CFNetDiagnosticDiagnoseProblemInteractively(diagRef); 
     CFStreamError error = CFReadStreamGetError(stream); 
     reportError(error); 
     CFReadStreamClose(stream); 
     CFRelease(stream); 
     break; 

Вы можете прочитать здесь - Using Network Diagnostics, CFNetDiagnostics Reference

+1

Нет, сценарий записи либо преуспевает, либо не выполняется, либо зависает (если нет свободного места и блокировка сокета). Я уверен, что этот сбой происходит, когда стек пытается указать приложению, что для записи доступно пространство, которое предлагает делегат-зомби. – dgatwood

2

Похоже класс сокет пытается отправить сообщение для делегата, а делегат стал зомби.

Класс NSStream не имеет сохраняет свой делегат, в отличие от большинства других сетевых классов в iOS/OS X, поэтому, если вы его где-то не сохраните, он исчезнет. Затем, когда класс пытается сообщить вашему классу, что у потока есть данные для чтения или места для записи, вы получите сбой в objc_msgSend, как этот.

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

Либо это, либо вам не удалось реализовать требуемый метод делегата. Однако это не соответствует бит «встречается редко». :-)

Смежные вопросы