1

编辑:我实际上将其追溯到我调用 [in open] 的行;并尝试打开输入流。出于某种原因,我的自定义类可能是无效的委托?我看到其他人有同样的错误,并且在将所有内容移动到 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 我该如何解决这个问题?谢谢!

4

1 回答 1

0

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

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

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

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

于 2013-05-27T15:45:09.433 回答