【发布时间】:2013-10-03 16:11:16
【问题描述】:
我一直在尝试为我的 iOS 应用程序启动并运行一个基本的 TCP 客户端,但遇到了一个我似乎无法解决的问题。
到目前为止,我可以连接,发送一条在服务器端收到但随后我的应用程序崩溃的消息。
客户端.h
#import <Foundation/Foundation.h>
@interface Client : NSObject <NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
}
-(void)initNetworkCommunication;
-(void)send:(NSString*)message;
@end
客户.m
#import "Client.h"
@implementation Client
- (void)initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.1.51", 7769, &readStream, &writeStream);
inputStream = ( NSInputStream *)CFBridgingRelease(readStream);
outputStream = ( NSOutputStream *)CFBridgingRelease(writeStream);
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)send:(NSString*)message
{
NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSUTF8StringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
}
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(@"stream event %i", streamEvent);
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);
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
NSLog(@"End Encountered!");
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
theStream = nil;
break;
default:
NSLog(@"Unknown event");
}
}
@end
控制台中的输出是
2013-10-03 17:01:38.542 MMORPG[6076:70b] stream event 1
2013-10-03 17:01:38.543 MMORPG[6076:70b] Stream opened
2013-10-03 17:01:43.495 MMORPG[6076:70b] stream event 4
2013-10-03 17:01:43.495 MMORPG[6076:70b] Unknown event
看起来,我的消息已发送,我收到了流事件 #4,然后我遇到了错误的访问崩溃。问题是我不知道它在访问时遇到了什么问题?
任何帮助将不胜感激!
【问题讨论】:
-
你能发布崩溃的堆栈跟踪吗? EXC_BAD_ACCESS 崩溃通常表示内存管理错误。使用 NSZombies 工具可能会帮助您找出问题所在。
-
启用僵尸后,我在输出中收到此额外消息 2013-10-03 17:48:43.989 MMORPG[6332:70b] *** -[Client respondsToSelector:]: message sent to deallocated instance 0x8ecffc0 这可能与我的对象实现的 NSStreamDelegate 有关吗?
-
是的,如果你的 NSStream 的委托(一个客户端实例)在流仍然存在并打开时被释放,你会遇到你描述的崩溃。您需要确保某些内容对客户端具有强引用,否则请确保在释放客户端之前关闭并释放流。
-
我多么愚蠢!好电话,在我的视图控制器中缺少一个强大的参考。我真的不知道我是怎么忽略的!
-
很高兴听到这个消息。我把我的评论变成了一个真实的答案,如果你愿意接受的话。
标签: objective-c tcpclient nsstream nsinputstream nsoutputstream