CFStreamCreatePairWithSocketToHost roto con el simulador ios6?

Noté que estaba obteniendo errores EXC_BADACCESS aleatorios al usar CFStreamCreatePairWithSocketToHost en mi progtwig, pero solo con ios6: cuando utilizo el simulador ios5 (incluso dentro del ios6sdk con xcode4.5) todo funciona bien. Terminé extrayendo el problema en un pequeño progtwig de testing que sigue: si habilitas el guardia malloc con esto, explotará de inmediato (ver el locking a continuación). También esto ocurre con arco y sin arco.

@interface PHAppDelegate : UIResponder <UIApplicationDelegate, NSStreamDelegate> { NSOutputStream* mOutputStream; NSInputStream* mInputStream; } @implementation PHAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSString* testAddress = @"192.168.1.0"; [self openWithHost:testAddress port:444]; return YES; } - (void)openWithHost:(NSString*)host port:(int)port { CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, /*ip_addr*/ port, &readStream, &writeStream); mInputStream = (NSInputStream *)readStream; mOutputStream = (NSOutputStream *)writeStream; if (mInputStream == nil) { NSLog(@"couldn't create the inputStream using CFStreamCreatePairWithSocketsToHost()"); return; } if (mOutputStream == nil) { NSLog(@"couldn't create the outputstream using CFStreamCreatePairWithSocketsToHost()"); return; } [mInputStream setDelegate:self]; [mOutputStream setDelegate:self]; [mInputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [mOutputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [mInputStream open]; [mOutputStream open]; } #pragma mark NSStream delegate methods - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { NSLog(@"stream-handleEvent"); } @end 

crash en com.apple.networking.connection thread:

 #0 0x04b35140 in tcp_connection_destination_prepare_complete () #1 0x04b34fee in tcp_connection_destination_start () #2 0x04b34c2b in tcp_connection_start_next_destination () #3 0x04b33c70 in tcp_connection_handle_reachability_changed () #4 0x04b30a95 in __tcp_connection_start_block_invoke_0 () #5 0x049fa53f in _dispatch_call_block_and_release () #6 0x04a0c014 in _dispatch_client_callout () #7 0x049fc418 in _dispatch_queue_drain () #8 0x049fc2a6 in _dispatch_queue_invoke () #9 0x049fd280 in _dispatch_root_queue_drain () #10 0x049fd450 in _dispatch_worker_thread2 () #11 0x94e7de12 in _pthread_wqthread () #12 0x94e65cca in start_wqthread () EXC_BADACCESS @ address 0x04b35140 0x04b3513b <+0072> call 0x4b332de <tcp_connection_destination_list_remove> 0x04b35140 <+0077> mov 0x28(%esi),%eax 0x04b35143 <+0080> test %eax,%eax 

Tengo un código muy similar que funciona para mí en iOS 5.xy iOS 6.x. La única diferencia es que inicializo CFReadStreamRef y CFWriteStreamRef a NULL antes de llamar a CFStreamCreatePairWithSocketToHost y paso NULL para el asignador. También suelo agregar el código como categoría en NSStream para mayor comodidad. Entonces, el código se ve así:

 + (void)createStreamsToHostNamed:(NSString*)hostName port:(NSInteger)port inputStream:(NSInputStream* __autoreleasing *)inputStream outputStream:(NSOutputStream* __autoreleasing *)outputStream { CFReadStreamRef readStream = NULL; CFWriteStreamRef writeStream = NULL; // Create a pair of of streams for a socket to the host specified CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)hostName, port, &readStream, &writeStream); // Assign the output parameters *inputStream = (__bridge_transfer NSInputStream*)readStream; *outputStream = (__bridge_transfer NSOutputStream*)writeStream; } 

Invocas el método con un código como este:

 @interface SomeClass : NSObject <NSStreamDelegate> @end @implementation SomeClass { NSInputStream* _inputStream; NSOutputStream* _outputStream; } - (void)_setupMethod { __autoreleasing NSInputStream* autoreleasingInputStream = nil; __autoreleasing NSOutputStream* autoreleasingOutputStream = nil; [NSStream createStreamsToHostNamed:kHostConstant port:kPortConstant inputStream:&autoreleasingInputStream outputStream:&autoreleasingOutputStream]; if(autoreleasingInputStream != nil && autoreleasingOutputStream != nil) { _inputStream = autoreleasingInputStream; [_inputStream setDelegate:self]; [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; _outputStream = autoreleasingOutputStream; [_outputStream setDelegate:self]; [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [_inputStream open]; [_outputStream open]; } } // NSStreamDelegate methods ... @end