感谢阅读!
我是iOS的新手,并按照通过telnet进行通信的聊天应用程序的教程进行操作 http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server
本教程是一个包含2个视图的单一视图控制器:第一个用于加入聊天会话,第二个用于聊天视图本身。 本教程有点旧,但我能够成功地使用最新的XCode 5.1.1。
我想要做的是创建第二个视图控制器,并能够指定IP /主机名然后连接。
所以我将[self initNetworkCommunication];
的调用从viewDidLoad
移到了一个单独的viewcontroller按钮(它仍然连接到与第一个视图相同的ViewController类。
我成功建立了一个telnet连接但是当我开始发送消息时,我得到 exc_bad_access code = 1 错误。我在第一个视图控制器上创建了一个按钮来做同样的事情,我没有遇到任何问题......
将此添加到 ViewController.m 并从viewDidLoad中删除了该调用
- (IBAction)connectToServer:(id)sender {
[self initNetworkCommunication];
}
那么,我该如何避免这个错误?
答案 0 :(得分:1)
你发生了两个全局变量,这通常不是一个好主意。
现在加载主视图,它也控制弹出视图控制器。这意味着将实例化同一视图控制器类的两个实例。现在,当您按下设置并显示弹出框时,主视图将被取消分配,因为没有人拥有它。因此,您可以在prepareForSegue:
中对其进行强有力的引用,但这并不是我为使其发挥作用而做的。
我遵循单例模式并创建了一个简单的ServerHelper,它包含一个共享的输入和输出流。然后我为Connect视图创建了一个简单的控制器,名为ConnectViewController
。
您可以在此处下载资源:http://www29.zippyshare.com/d/16861250/9924/TelnetChatTest-master.zip
修改强>
要即时连接到服务器,请转到ConnectViewController.m
并添加
[[ServerHelper sharedInstance] connectToIP:self.ipAddress.text port:80];
到connectToServer:
在服务器帮助程序中,将以下内容添加到@interface ServerHelper: NSObject
- (void)connectToIP:(NSString *)IP port:(int)port;
将当前setStreamDelegate:
替换为:
- (void)setStreamDelegate:(id<NSStreamDelegate>)streamDelegate {
_streamDelegate = streamDelegate;
self.inputStream.delegate = streamDelegate;
self.outputStream.delegate = streamDelegate;
}
删除ServerHelper&#39; init
的所有内容并执行以下操作:
- (void)connectToIP:(NSString *)IP port:(int)port
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStringRef ipRef = (__bridge CFStringRef)IP;
CFStreamCreatePairWithSocketToHost(NULL, ipRef, port, &readStream, &writeStream);
self.inputStream = (NSInputStream *)CFBridgingRelease(readStream);
self.outputStream = (NSOutputStream *)CFBridgingRelease(writeStream);
self.inputStream.delegate = self.streamDelegate;
self.outputStream.delegate = self.streamDelegate;
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream open];
}
答案 1 :(得分:0)
您可以在“ViewController”类的第二个实例中创建流。因此,在第一个控制器中,输入和输出流未初始化。
您应该为弹出窗口创建(例如)另一个控制器,并为主控制器创建委托。点击popover上的连接按钮后,您应该从popover控制器向委托([delegate connectToServer])发送一些消息,然后在主控制器中初始化流。