Технические вопросы и ответы QA1546

NSNetService и Automatic Reference Counting (ARC)

Q: Я создаю пару потокового использования -[NSNetService getInputStream:outputStream:] и после преобразования моего проекта к автоматическому подсчету ссылок (ARC) мои потоки отказываются открываться должным образом. Что вызывает это?

A: -[NSNetService getInputStream:outputStream:] имеет много выдающихся ошибок (r. 6868813) (r. 9821932) (r. 9856751), некоторые из которых усилены ARC. Лучшим способом избежать всех этих проблем является к выпадающему уровень и использование CFStreamCreatePairWithSocketToNetService создать Ваши потоки. Код в Перечислении 1 показывает, как можно создать категорию на NSNetService, обеспечивающем функциональную замену для -[NSNetService getInputStream:outputStream:].

Перечисление 1  функциональная замена для - [NSNetService getInputStream:outputStream:]

@interface NSNetService (QNetworkAdditions)
 
- (BOOL)qNetworkAdditions_getInputStream:(out NSInputStream **)inputStreamPtr
    outputStream:(out NSOutputStream **)outputStreamPtr;
 
@end
 
@implementation NSNetService (QNetworkAdditions)
 
- (BOOL)qNetworkAdditions_getInputStream:(NSInputStream **)inputStreamPtr
    outputStream:(NSOutputStream **)outputStreamPtr
{
    BOOL                result;
    CFReadStreamRef     readStream;
    CFWriteStreamRef    writeStream;
 
    result = NO;
 
    readStream = NULL;
    writeStream = NULL;
 
    if ( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) ) {
        CFNetServiceRef     netService;
 
        netService = CFNetServiceCreate(
            NULL,
            (__bridge CFStringRef) [self domain],
            (__bridge CFStringRef) [self type],
            (__bridge CFStringRef) [self name],
            0
        );
        if (netService != NULL) {
            CFStreamCreatePairWithSocketToNetService(
                NULL,
                netService,
                ((inputStreamPtr  != NULL) ? &readStream : NULL),
                ((outputStreamPtr != NULL) ? &writeStream : NULL)
            );
            CFRelease(netService);
        }
 
        // We have failed if the client requested an input stream and didn't
        // get one, or requested an output stream and didn't get one. We also
        // fail if the client requested neither the input nor the output
        // stream, but we don't get here in that case.
 
        result = ! ((( inputStreamPtr != NULL) && ( readStream == NULL)) ||
                    ((outputStreamPtr != NULL) && (writeStream == NULL)));
    }
    if (inputStreamPtr != NULL) {
        *inputStreamPtr  = CFBridgingRelease(readStream);
    }
    if (outputStreamPtr != NULL) {
        *outputStreamPtr = CFBridgingRelease(writeStream);
    }
 
    return result;
}
 
@end


История версии документа


ДатаПримечания
28.10.2011

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