exc_bad_access code = 1从viewDidLoad移动方法调用时

时间:2014-08-15 15:02:05

标签: ios objective-c iphone xcode

感谢阅读!

我是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];

}

那么,我该如何避免这个错误?

*我已将代码放在https://github.com/ervine13/TelnetChatTest

2 个答案:

答案 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])发送一些消息,然后在主控制器中初始化流。