Это чувство погружения, когда ты понимаешь, что понятия не имеешь, что происходит ...
Я использую этот код в своем сетевом коде почти два года без проблем.
if (!CFReadStreamOpen(myReadStream)) {
CFStreamError myErr = CFReadStreamGetError(myReadStream);
if (myErr.error != 0) {
// An error has occurred.
if (myErr.domain == kCFStreamErrorDomainPOSIX) {
// Interpret myErr.error as a UNIX errno.
strerror(myErr.error);
} else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
OSStatus macError = (OSStatus)myErr.error;
}
// Check other domains.
}
}
Я полагаю, что он изначально был основан на приведенных здесь примерах кода:
http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/CFNetwork/CFStreamTasks/CFStreamTasks.html
Однако недавно я заметил, что некоторые соединения не работают, потому что CFReadStreamOpen возвращает false, но код ошибки равен 0. После еще одного взгляда на вышеуказанную ссылку я заметил оператор CFRunLoopRun () и добавил его:
if (!CFReadStreamOpen(myReadStream)) {
CFStreamError myErr = CFReadStreamGetError(myReadStream);
if (myErr.error != 0) {
// An error has occurred.
if (myErr.domain == kCFStreamErrorDomainPOSIX) {
// Interpret myErr.error as a UNIX errno.
strerror(myErr.error);
} else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
OSStatus macError = (OSStatus)myErr.error;
}
// Check other domains.
} else
// start the run loop
CFRunLoopRun();
}
Это исправило проблему с подключением. Однако мое приложение начало показывать случайные проблемы - интерфейс иногда не реагировал или не рисовал, текстовые поля не редактировались, что-то в этом роде.
Я прочитал о CFReadStreamOpen и о циклах выполнения (в частности, о том, что основной цикл выполнения выполняется сам по себе, и я не должен запускать цикл выполнения, пока я сам не настрою его во вторичном потоке - что я ' м нет, насколько я знаю). Но я все еще не понимаю, что на самом деле происходит выше. В частности:
1) Почему CFReadStreamOpen иногда возвращает FALSE и код ошибки 0? Что это на самом деле означает?
2) Что на самом деле делает вызов CFRunLoopRun в приведенном выше коде? Почему пример кода выполняет этот вызов - если этот код выполняется в главном потоке, мне не нужно запускать цикл выполнения?