2012-04-21 82 views
1

编辑:我实际上追溯到我打电话[打开]的行;并尝试打开输入流。出于某种原因,我的自定义类可能是一个无效的代理?我看到其他人有相同的错误,并没有问题后,将所有内容移动到ViewController子类而不是扩展NSObject的自定义类。但是,我仍然想使用我自己的自定义类而不是ViewController之一。iOS5:为什么在main.m中setDelegate:self会导致EXC_BAD_ACCESS?

我有一个连接类,我编码自己,我使用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 如何解决这个问题?谢谢!

+0

我对这些类不太熟悉,但NSStream(NSInput/Output流继承自)的文档说:'委托和setDelegate: 返回并设置委托。默认情况下,流对象必须是它自己的委托;所以一个参数为nil的setDelegate:消息应该还原这个委托。' – lnafziger 2012-04-21 05:01:28

+0

委托对象是否有可能在该行的某处被释放和释放? – Bryan 2012-04-21 22:43:51

回答

0

发生什么事是因为你没有保留它,或者你正在使用ARC(漂亮的),所以正在释放Connection类(它被设置为委托)的任何实例(在运行循环中导致EXC_BAD_ACCESS)可能),而你没有提及它。

的解决方法是调用保留在连接类,像这样:

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

或者如果你启用了ARC,使一个实例变量的类,你ALLOC连接,存储您的实例在那里连接。这样ARC就不会解除它的分配,因为实例变量var作为参考。

相关问题