Baub
Baub

Reputation: 5044

EXC_Bad_Access When Calling Method from Class

All,

I have a view controller (let's call it testViewController) that calls a method in another class (class name scan, method name initNetworkCommunication).

Here is the view controller's button method:

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

And here is the class

//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

I'm getting the EXC_BAD_ACCESS, and when I enable NSZombieEnable, my debugging session looks like this:

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) 

It crashes at the three asterisks, and that's my zombie message.

What should I do?

EDIT:After running the program in Instruments, I see no memory leaks. The thing that's getting me is showing in Instruments as SocketStream::dispatchSignalFromSocketCallbackUnlocked(SocketStream)

Upvotes: 1

Views: 3455

Answers (3)

ETech
ETech

Reputation: 1607

Just remove inputStream and outputStream from properties and let them stay only class variables.
In case of ARC, it helps.

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

In my case, it solved all problems. Was impossible to solve it other way.

Upvotes: 0

Morten Fast
Morten Fast

Reputation: 6320

You have forgotten to retain the Scan object that is the stream's delegate.

Until the streams are closed, your stream delegate will receive messages, and if the delegate gets deallocated, then your app will crash.

In your example code (where you're leaking the canConnect object) it should be fine, but in your real code you might be releasing the Scan object too soon.

Upvotes: 5

change inputStream , outputStream to with self with dot syntax everywhere

like this everywhere

because if u synthesize the property u have to use self with dot syntax to retain them .

self.inputStream = (NSInputStream *) readStream;

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

i suggest u to change name of function

initNetworkCommunication to some

Upvotes: 0

Related Questions