3

我正在编写一个使用 NSOutputStream 的应用程序。我像这样初始化连接:

delegate = self;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)url,port, &readStream, &writeStream);
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

inputStream = (__bridge_transfer NSInputStream *)readStream;
outputStream = (__bridge_transfer NSOutputStream *)writeStream;

[inputStream setDelegate:delegate];
[outputStream setDelegate:delegate];

loop = [NSRunLoop currentRunLoop];
[inputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];

[inputStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
[outputStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];



[inputStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL
                  forKey:NSStreamSocketSecurityLevelKey];
[outputStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL
                   forKey:NSStreamSocketSecurityLevelKey];

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
                          [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                          [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                          [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
                          kCFNull,kCFStreamSSLPeerName,
                          nil];

CFReadStreamSetProperty((CFReadStreamRef)inputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty((CFWriteStreamRef)outputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);

[outputStream open];
[inputStream open];

[self sendVersionOrWait];
[loop run];

然后根据 NSStreamDelegate 方法做一些动作。关闭连接通过以下方式完成:

 [inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil];
[outputStream setDelegate:nil];

inputStream = nil;
outputStream = nil;

有时(它是随机的)我得到 EXC_BREAKPOINT 并且应用程序崩溃。这是崩溃日志的一部分:

异常类型:EXC_BREAKPOINT (SIGTRAP) 异常代码:0x0000000000000001、0x000000000000defe 由线程触发:5

线程 5 名称:调度队列:com.apple.root.default-qos

线程 5 崩溃:

0 核心基础 0x22767e22 CFHash + 130

1 核心基础 0x22768d70 CFBasicHashGetCountOfKey + 1152

2 核心基础 0x227688aa CFSetContainsValue + 98

3 核心基础 0x2279ca5a CFRunLoopRemoveSource + 226

4 CFNetwork 0x22343eca SocketStream::write(__CFWriteStream*, unsigned char const*, long, CFStreamError*) + 426

5 CFNetwork 0x223480c2 WriteStreamCallbacks::_write(__CFWriteStream*, unsigned char const*, long, CFStreamError*, void*) + 34

6 核心基础 0x2278d7ec CFWriteStreamWrite + 356

7 应用程序 0x000a0190-[AppMenuViewController sendVersion] (AppMenuViewController.m:763)

8 应用程序 0x000a0c68-[AppMenuViewController sendVersionOrWait] (AppMenuViewController.m:832)

9 基础 0x235655e4 __NSFireDelayedPerform + 464

10 核心基础 0x22828734 CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 12

11 核心基础 0x228282b4 __CFRunLoopDoTimer + 652

12 核心基础 0x2282651e __CFRunLoopRun + 1414

13 核心基础 0x22773dac CFRunLoopRunSpecific + 472

14 核心基础 0x22773bbe CFRunLoopRunInMode + 102

15 基础 0x234ab16c -[NSRunLoop(NSRunLoop) 运行模式:beforeDate:] + 260

16 基础 0x234f95e0 -[NSRunLoop(NSRunLoop) 运行] + 76

17 应用程序 0x0009feaa-[AppMenuViewController initConnection:withPort:] (AppMenuViewController.m:749)

18 应用程序 0x000a1642-[AppMenuViewController 流:handleEvent:](AppMenuViewController.m:952)

19 核心基础 0x227d9b94 _signalEventSync + 144

20 核心基础 0x227e3ef2 _cfstream_solo_signalEventSync + 198

21 核心基础 0x227d981e _CFStreamSignalEvent + 322

22 CFNetwork 0x222b7bd4 SocketStream::dispatchSignalFromSocketCallbackUnlocked(SocketStreamSignalHolder*) + 36

23 CFNetwork 0x222b78be SocketStream::socketCallback(__CFSocket*, unsigned long, __CFData const*, void const*) + 146

24 CFNetwork 0x222b77f2 SocketStream::_SocketCallBack_stream(__CFSocket*, unsigned long, __CFData const*, void const*, void*) + 54

25 核心基础 0x2282b0bc __CFSocketPerformV0 + 552

26 核心基础 0x22828804 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 12

27 核心基础 0x22827c16 __CFRunLoopDoSources0 + 218

28 核心基础 0x22826294 __CFRunLoopRun + 764

29 核心基础 0x22773dac CFRunLoopRunSpecific + 472

30 核心基础 0x22773bbe CFRunLoopRunInMode + 102

31 基础 0x234ab16c -[NSRunLoop(NSRunLoop) 运行模式:beforeDate:] + 260

32 基础 0x234f95e0 -[NSRunLoop(NSRunLoop) 运行] + 76

33 应用程序 0x0009feaa-[AppMenuViewController initConnection:withPort:] (AppMenuViewController.m:749)

34 应用程序 0x0009b664 __58-[AppMenuViewController alertView:clickedButtonAtIndex:]_block_invoke (AppMenuViewController.m:385)

35 libdispatch.dylib 0x30521610 _dispatch_call_block_and_release + 8

36 libdispatch.dylib 0x3052d350 _dispatch_root_queue_drain + 816

37 libdispatch.dylib 0x3052e27a _dispatch_worker_thread3 + 102

38 libsystem_pthread.dylib 0x3069ee22 _pthread_wqthread + 666

39 libsystem_pthread.dylib 0x3069eb74 start_wqthread + 4

我想这可能是由网络问题引起的,因为它出现在我的 WIFI 路由器没有 Internet 连接时。但我不确定,也不知道如何消除此错误。请帮忙 :)

4

1 回答 1

0

我的猜测是这与线程有关。尝试对主线程进行调度,以确保这一切都在主线程上完成,看看这是否能神奇地解决问题。如果是这样,你知道去哪里找......

于 2015-03-02T11:01:11.427 回答