2012-10-01 25 views
8

Tôi nhận thấy tôi đã nhận được lỗi EXC_BADACCESS ngẫu nhiên khi sử dụng CFStreamCreatePairWithSocketToHost trong chương trình của tôi, nhưng chỉ với ios6 - khi sử dụng trình mô phỏng ios5 (ngay cả bên trong ios6sdk với xcode4.5) mọi thứ hoạt động tốt. Tôi đã kết thúc việc giải nén vấn đề thành một chương trình thử nghiệm nhỏ sau - nếu bạn kích hoạt bảo vệ malloc với điều này nó sẽ thổi lên ngay lập tức (xem sự cố bên dưới). Ngoài ra điều này xảy ra w/arc và phi arc.CFStreamCreatePairWithSocketToHost bị hỏng với trình mô phỏng ios6?

@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 

sụp đổ trong chủ đề com.apple.networking.connection:

#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 
+0

Tôi đã cùng một vấn đề xảy ra trên iOS6 nhưng không xảy ra trên iOS 5, bạn có Có bất kỳ cập nhật nào không? –

+0

không cập nhật - vẫn xảy ra. – jazios

Trả lời

0

tôi có mã cực kỳ tương tự mà làm việc cho tôi trong iOS 5.x và iOS 6.x. Điểm khác biệt duy nhất là tôi khởi tạo CFReadStreamRefCFWriteStreamRef đến NULL trước khi gọi CFStreamCreatePairWithSocketToHost và tôi chuyển NULL cho người cấp phát. Tôi cũng thường thêm mã làm danh mục trên NSStream để thuận tiện. Vì vậy, các mã trông giống như sau:

+ (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; 
} 

Bạn sẽ gọi phương pháp này với một số mã như thế này:

@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 
Các vấn đề liên quan