Как решить выделенное соединение в iPhone SDK 3.1.3? - Потоки - CFSockets - PullRequest
0 голосов
/ 18 марта 2010

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

Сначала у меня есть два класса, вовлеченных в проблему: класс публикации (где выполняется публикация службы и конфигурирование сокета) и соединение (где выполняется привязка сокета и конфигурация потоков). Основная проблема заключается в подключении через родной сокет. В классе «публикация» «сервер» принимает соединение с обратным вызовом. Обратный вызов имеет информацию о собственном сокете. Затем создается соединение с информацией собственного сокета. Затем выполняется привязка сокета и настройка потоков. Когда эти действия успешны, экземпляр соединения сохраняется в непостоянном массиве. Таким образом, связь установлена.

static void AcceptCallback(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
  Publish *rePoint = (Publish *)info;

  if ( type != kCFSocketAcceptCallBack) {
   return;
  }
  CFSocketNativeHandle nativeSocketHandle = *((CFSocketNativeHandle *)data);
  NSLog(@"The AcceptCallback was called, a connection request arrived to the server");
  [rePoint handleNewNativeSocket:nativeSocketHandle];
}
- (void)handleNewNativeSocket:(CFSocketNativeHandle)nativeSocketHandle{
 Connection *connection = [[[Connection alloc] initWithNativeSocketHandle:nativeSocketHandle] autorelease]; // Create the connection
 if (connection == nil) {
  close(nativeSocketHandle);
  return;
 }
 NSLog(@"The connection from the server was created now try to connect");
 if ( ! [connection connect]) {
  [connection close];
  return;
 }

 [clients addObject:connection];  //save the connection trying to avoid the deallocation
}

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

void myReadStreamCallBack (CFReadStreamRef stream, CFStreamEventType eventType, void *info) {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  Connection *handlerEv = [[(Connection *)info retain] autorelease];   // The error -[Connection retain]: message sent to deallocated instance 0x1f5ef0 (Where 0x1f5ef0 is the reference to the  established connection)
  [handlerEv readStreamHandleEvent:stream andEvent:eventType];
 [pool drain];

}

void myWriteStreamCallBack (CFWriteStreamRef stream, CFStreamEventType eventType, void *info){
 NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
   Connection *handlerEv = [[(Connection *)info retain] autorelease];  //Sometimes the error also happens here, I tried without the pool, but it doesn't help neither.
                  [handlerEv writeStreamHandleEvent:eventType];
 [p drain];

}

Что-то странное в том, что когда я запускаю отладчик (с точками останова), все идет хорошо, соединение не освобождается и обратные вызовы работают нормально, и сервер может получать сообщение. Буду признателен за любую подсказку!

1 Ответ

0 голосов
/ 19 марта 2010

Я удаляю авторелиз из этой строки:

Connection *handlerEv = [[(Connection *)info retain] autorelease];

Теперь, похоже, работает, но я попробую больше вещей, потому что я не уверен, когда выйдет и будут ли у меня "побочные эффекты"

Пожалуйста, любая подсказка очень полезна!

...