iOS5:为什么setDelegate:self会导致main.m中出现EXC_BAD_ACCESS?

时间:2012-04-21 02:20:56

标签: ios5

编辑:我实际上是将它追踪到我打电话的地方[打开];并尝试打开输入流。出于某种原因,我的自定义类可能是无效的委托?我看到其他人有相同的错误,并且在将所有内容移动到ViewController子类而不是扩展NSObject的自定义类之后没有问题。但是,我仍然想使用我自己的自定义类而不是ViewControllers之一。

我有一个我自己编写的Connection类,我使用NSInputStream和NSOutputStream。我在init方法中初始化流:

- (id)init {
    self = [super init];
    if(self) {
        messages = [NSMutableArray new];

        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)HOST, PORT, &readStream, &writeStream);
        [self setIn: (__bridge_transfer NSInputStream *)readStream];
        [self setOut: (__bridge_transfer NSOutputStream *)writeStream];
        NSLog(@"Streams opened.");
        NSLog(@"ConnectionController initialized...");
    }
    return self;
}

此外,这里是.h

中我的连接类的定义
@interface ConnectionController : NSObject <NSStreamDelegate> {
    NSMutableArray *messages;
}

@property (strong, nonatomic) NSInputStream *in;
@property (strong, nonatomic) NSOutputStream *out;

-(void)sendMessage:(NSString*)msg;
-(void)stream:(NSStream *)eStream handleEvent:(NSStreamEvent)eventCode;
-(void)messageReceived:(NSString*)msg;
@end

当我调用此方法openStreams时,我得到EXC_BAD_ACCESS

- (void)openStreams {
    [in setDelegate:self];
    [out setDelegate:self];

    [in scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [out scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [in open];
    [out open];
}

当我注释掉setDelegate:self时,不会发生错误。但是,我需要这个以便使用事件驱动的方法来处理NSStreamEvents 我该如何解决?谢谢!

1 个答案:

答案 0 :(得分:0)

正在发生的事情是Connection类(设置为委托)的任何实例都被释放(在运行循环中导致EXC_BAD_ACCESS),因为你没有保留它,或者你正在使用ARC(很可能) )你没有参考它。

解决方案是在连接类上调用retain,如下所示:

Connection *connection = [[Connection alloc] init];
[connection retain];

或者,如果您确实启用了ARC,请在分配Connection的类中创建一个实例变量,并在那里存储您的连接实例。这样ARC就不会释放它,因为实例var计为一个参考。