Technical Q&A QA1546

NSNetService and Automatic Reference Counting (ARC)

Q:  I create a pair of streams using -[NSNetService getInputStream:outputStream:] and, after converting my project to automatic reference counting (ARC), my streams refuse to open properly. What's causing this?

A: -[NSNetService getInputStream:outputStream:] has a number of outstanding bugs (r. 6868813) (r. 9821932) (r. 9856751) , some of which are exacerbated by ARC. The best way to avoid all of these problems is to drop down a level and use CFStreamCreatePairWithSocketToNetService to create your streams. The code in Listing 1 shows how you can create a category on NSNetService that provides a functional replacement for -[NSNetService getInputStream:outputStream:].

Listing 1  A functional replacement for -[NSNetService getInputStream:outputStream:]

@interface NSNetService (QNetworkAdditions)
- (BOOL)qNetworkAdditions_getInputStream:(out NSInputStream **)inputStreamPtr
    outputStream:(out NSOutputStream **)outputStreamPtr;
@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(
            (__bridge CFStringRef) [self domain],
            (__bridge CFStringRef) [self type],
            (__bridge CFStringRef) [self name],
        if (netService != NULL) {
                ((inputStreamPtr  != NULL) ? &readStream : NULL),
                ((outputStreamPtr != NULL) ? &writeStream : NULL)
        // 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;

Document Revision History


New document that describes an issue with NSNetService that can cause connections never to complete.