所有
我通过评论,断点等来运行它。程序在标记的代码处崩溃。
-(void) initNetworkCommunication
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.17.1", 2004, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];//WHY MUST YOU CRASH HERE
[outputStream open];//WHY MUST YOU CRASH HERE ALSO!!?!?
NSLog(@"She be opened, sir!");
}
如果我注释掉这两个,它不会崩溃,但是如果我注释掉任何一个它会崩溃(因此它们都会导致程序崩溃)。也没有在调试器中发布的信息。它只是将我发送到main.m并告诉我
“线程1:编程接收信号:”EXC_BAD_ACCESS“。
提前感谢您的帮助!
编辑:这是我的委托方法,但它甚至不会在日志中显示第二个有效行。
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(@"stream event %i", streamEvent); //this doesn't post in the log when stream opened...
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream) {
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != output) {
NSLog(@"server said: %@", output);
//[self messageReceived:output];
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//[theStream release];
theStream = nil;
break;
default:
NSLog(@"Unknown event");
}
}
答案 0 :(得分:4)
发生的事情是委托类的实例被释放(在运行循环中导致EXC_BAD_ACCESS),因为你没有保留它,或者你正在使用ARC(很可能)并且你没有引用它。
解决方案是在委托类上调用retain,大致如下:
SomeStreamDelegate *theDelegate = [[SomeStreamDelegate alloc] init];
[theDelegate retain];
或者,如果您确实启用了ARC,请在分配代理的类中创建一个实例变量,并在那里存储您的连接实例。这样ARC就不会释放它,因为实例var计为一个参考。
答案 1 :(得分:2)
如果您使用的是ARC,请像这样投射流:
inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
这可以防止崩溃。请记住,如果您的流由一个单独的线程拥有而不是主线程,这意味着在打开流后需要使用run方法手动调用运行循环。
答案 2 :(得分:1)
当我将它放在我的视图控制器中(而不是在一个单独的类中)时,它完美地工作。
答案 3 :(得分:0)
我有一个类似的问题,我的应用程序会在-handleEvent回调中崩溃,并带有一个巨大的streamEvent数字。我通过确保初始化NSStream对象(输入和输出)来解决它。 AND 在我计划使用的NetworkClient对象的-init方法中打开与服务器的连接。
答案 4 :(得分:-2)