Хобрук: Ваш путь к мастерству в программировании

Какао, бесплатный мост и ARC

Я хочу сделать простой клиент TCP. Но я получаю одну ошибку. Когда я делаю inputStream = (NSInputStream *)readStream; и outputStream = (NSOutputStream *)writeStream;, мне предлагается ввести префикс __bridge или _bridge_transfer.

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

Я только что разместил здесь сообщение initNetworkCommunication, потому что именно здесь я получаю ошибку «моста».

- (void) initNetworkCommunication {

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"54.xxx.xxx.xxx", 1333, &readStream, &writeStream);

    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];

}

Сервер в порядке, потому что я попробовал пример кода и получил ответ.

Можете вы помочь мне?


  • 1. Эти ключевые слова — ерунда, связанная с ARC; вам лучше отключить ARC для этого проекта. 2. Я создал TCP-оболочку Objective-C для API сокетов BSD, которая очень проста в использовании: github. com/H2CO3/TCPHelper 13.07.2012

Ответы:


1

Как упоминалось в H2CO3, это вещь ARC.

Если вы не знаете, что такое ARC, прочитайте это. Подводя итог, можно сказать, что это детерминированный способ автоматизации управления памятью (операторы сохранения/освобождения и т. д.), который ранее программистам на Objective-C приходилось делать вручную. Его стоит использовать, и у него мало недостатков. Тем не менее, у него есть несколько ошибок.

ARC не работает с объектами Core Foundation. Они по-прежнему подчиняются старым правилам, согласно которым вы должны сами управлять памятью. ARC применяется только к объектам Objective-C. Тем не менее, некоторые объекты Core Foundation на самом деле бесплатно подключены к их эквиваленту Cocoa. Вы используете бесплатный мост в своем примере кода, чтобы создать CFReadStreamRef, а затем работать с ним как с NSInputStream.

Ну так что ты делаешь? Документы Apple говорят следующее:

Если вы выполняете приведение между объектами в стиле Objective-C и Core Foundation, вам необходимо сообщить компилятору о семантике владения объектом, используя либо приведение (определенное в objc/runtime.h), либо макрос в стиле Core Foundation (определенное в NSObject.h):

  • __bridge передает указатель между Objective-C и Core Foundation без передачи права собственности.
  • __bridge_retained или CFBridgingRetain приводит указатель Objective-C к указателю Core Foundation, а также передает вам право собственности. Вы несете ответственность за вызов CFRelease или связанной с ним функции для отказа от владения объектом.
  • __bridge_transfer или CFBridgingRelease перемещает указатель не-Objective-C в Objective-C, а также передает право собственности на ARC. ARC несет ответственность за отказ от права собственности на объект.

Вы переходите с Core Foundation на Objective-C, поэтому игнорируйте второй пункт (это для движения в другом направлении). Вопрос в том, что вы хотите, чтобы произошло — если после передачи вы хотите передать этот объект в ARC, использовать его только со стороны Objective-C, а ARC должен заниматься управлением памятью, используйте __bridge_transfer. Это, вероятно, то, что вы хотите, основываясь на вашем примере кода.

Если вы просто используете __bridge или не используете ARC, вам нужно очистить объекты самостоятельно, используя либо CFRelease(), либо отправив им сообщение release (последнее работает, только если вы не используете ARC).

13.07.2012
  • Большое спасибо, Эми Уорролл. Ну, я пришел из простого Javascript и HTML Front End. Сижу на IOS около 2-х месяцев, и пришло время покупать книгу. Большое спасибо за объяснение. 13.07.2012
  • Не волнуйтесь. ARC, безусловно, будущее, поэтому его стоит использовать, но мы находимся в переходном периоде, когда он все еще нов, а многие учебные пособия еще не обновлены. Убедитесь, что когда вы получаете книгу, вы знаете, учит ли она старым (ручное сохранение/освобождение) правилам управления памятью или использует ARC. По крайней мере, стоит знать о ручном способе работы, поскольку это дает вам лучшее понимание того, что автоматизирует ARC. 13.07.2012
  • Я понимаю. Ну, добавление __bridge_transfer не сработает. My - (void) sendMessage:(NSString *)message { NSLog(@message %@,message); NSData *data = [[NSData alloc] initWithData:[данные сообщенияUsingEncoding:NSASCIIStringEncoding]]; [outputStream write:[байты данных] maxLength:[длина данных]]; NSLog(@outputStream %@,outputStream); } не работает :S Я думаю, проблема с выходным потоком 13.07.2012
  • Новые материалы

    Прогресс в технологии Трансформеров часть 3
    Многомасштабный управляющий сигнальный преобразователь для бесфазного синтеза движения (arXiv) Автор: Линтао Ван , Кун Ху , Лей Бай , Юй Дин , Ваньли Оуян , Чжиюн Ван . Аннотация:..

    Представляем поддержку компонентов Vue.js. Мгновенный HMR и многое другое.
    Хотя у FuseBox уже был плагин Vue, он был базовым и не имел многих функций, которые делали работу с Vue.js такой приятной. Однако с этим выпуском мы рады сообщить, что в FuseBox..

    Приключения в Javascript, часть 1
    Я продолжаю думать о том, чтобы писать больше, но чем больше я думаю об этом, тем меньше я это делаю. Итак, сегодня я перестал думать и начал писать. Отсюда можно только спускаться… В..

    Понимание дженериков в TypeScript: подробное руководство
    Введение TypeScript, строго типизированный надмножество JavaScript, хорошо известен своей способностью улучшать масштабируемость, удобочитаемость и ремонтопригодность приложений. Одной из..

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..