从类调用方法时的EXC_Bad_Access

时间:2011-07-15 17:19:12

标签: iphone objective-c xcode

所有

我有一个视图控制器(我们称之为testViewController),它调用另一个类中的方法(类名扫描,方法名称为initNetworkCommunication)。

这是视图控制器的按钮方法:

-(IBAction) test
{
    Scan *canConnect = [[Scan alloc] init];
    [canConnect initNetworkCommunication];
}

这是班级

//scan.h

@interface Scan : NSObject <NSStreamDelegate>
{
    NSInputStream *inputStream;
    NSOutputStream *outputStream;
}

-(void) scan;
-(void) initNetworkCommunication;

@property (nonatomic, retain) NSInputStream *inputStream;
@property (nonatomic, retain) NSOutputStream *outputStream;


@end

//scan.m

#import "Scan.h"

@implementation Scan

@synthesize inputStream, outputStream;

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

-(void) initNetworkCommunication
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.17.1", 2004, &readStream, &writeStream);
    NSLog(@"readStream %@", readStream);
    NSLog(@"writeStream %@", writeStream);
    inputStream = (NSInputStream *) readStream;
    outputStream = (NSOutputStream *) writeStream;//this __strong may work!
    NSLog(@"inputStream %@", inputStream);
    NSLog(@"outputStream %@", outputStream);
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
    NSLog(@"She be opened, sir!");
    return;
}
//more code is here, dealloc, etc

我正在获取EXC_BAD_ACCESS,当我启用NSZombieEnable时,我的调试会话如下所示:

2011-07-15 13:09:46.210 Project[1176:f203] readStream <__NSCFInputStream: 0x6e7a2a0>
2011-07-15 13:09:46.212 Project[1176:f203] writeStream <__NSCFOutputStream: 0x6e7a340>
2011-07-15 13:09:46.213 Project[1176:f203] inputStream <__NSCFInputStream: 0x6e7a2a0>
2011-07-15 13:09:46.214 Project[1176:f203] outputStream <__NSCFOutputStream: 0x6e7a340>
2011-07-15 13:09:46.215 Project[1176:f203] She be opened, sir!
2011-07-15 13:09:46.220 Project[1176:f203] *** -[Scan respondsToSelector:]: message sent to deallocated instance 0x6e79b20
Current language:  auto; currently objective-c
(gdb) 

它在三个星号上崩溃了,那是我的僵尸信息。

我该怎么办?

编辑:在Instruments中运行程序后,我看到没有内存泄漏。得到我的东西在Instruments中显示为SocketStream :: dispatchSignalFromSocketCallbackUnlocked(SocketStream)

3 个答案:

答案 0 :(得分:5)

您忘记保留作为流代理的Scan对象。

在流关闭之前,您的流委托将接收消息,如果委托被取消分配,那么您的应用程序将崩溃。

在您的示例代码中(您泄漏canConnect对象的地方)应该没问题,但在您的实际代码中,您可能会过早发布Scan对象。

答案 1 :(得分:0)

将inputStream,outputStream更改为self with dot syntax where无处不在

到处都是

因为如果您合成属性,则必须使用带有点语法的self来保留它们。

self.inputStream = (NSInputStream *) readStream;

self.outputStream = (NSOutputStream *) writeStream;//this __strong may work!

我建议你改变功能名称

initNetworkCommunication到某些

答案 2 :(得分:0)

只需从属性中删除inputStream和outputStream,让它们只保留类变量 如果是ARC,它会有所帮助。

@interface Scan: NSObject <NSStreamDelegate> {
    NSInputStream * inputStream;
    NSOutputStream * outputStream;
}
....
@end

就我而言,它解决了所有问题。不可能以其他方式解决它。