Search code examples
objective-ciosmemory-managementdealloc

exc_bad_access on super dealloc in MyDownloader implementation


I've implemented the MyDownloader class defined in Nueburg's Programing ios 4. When I run the code, I get an exc_bad_access on the super dealloc. The book does not provide a description on the header file, so perhaps I did something wrong there. Could someone please help my see what is causing the error?

Here is my header file:

#import <Foundation/Foundation.h>


@interface MyDownloader : NSURLConnection {
    NSURLConnection *connection;
    NSURLRequest    *request;
    NSMutableData   *receivedData;
}

-(id) initWithRequest: (NSURLRequest*) req;

@property (nonatomic, retain) NSURLConnection   *connection;
@property (nonatomic, retain) NSURLRequest      *request;
@property (nonatomic, retain) NSMutableData     *receivedData;

@end

Here is my implementation (minus the implementation of didReceiveResponse, didReceiveData, didFailWithError, and connectionDidFinishLoading which was all taken right out of the book):

#import "MyDownloader.h"


@implementation MyDownloader

@synthesize connection;
@synthesize request;
@synthesize receivedData;

-(id) initWithRequest: (NSURLRequest*) req {
    self = [super init];
    if (self) {
        self->request = [req copy];

        // Create a connection, but don't start it yet. The connection will be started with a start message.
        self->connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
        self->receivedData = [[NSMutableData alloc] init];  // initialize where the incoming data will be stored
    }
    return self;
}

- (void)dealloc
{
    [receivedData release];
    [request release];
    [connection release];
    [super dealloc];
}
...
@end

And finally, here is my use of the class:

{
     ...
     if (!self.connections) {
     self.connections = [NSMutableArray array];
     }
     NSString *s = @"https://www.myserver.com/myfile.txt";
     NSURL *url = [NSURL URLWithString:s];
     NSURLRequest *req = [NSURLRequest requestWithURL:url];
     MyDownloader *d = [[MyDownloader alloc] initWithRequest:req];
     [self.connections addObject:d];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadFinished:) name:@"connectionFinished" object:d];
     [d.connection start];
     [d release];
    ...
}

-(void) downloadFinished: (NSNotification *) n 
{
    MyDownloader *d = [n object];
    NSData *data = nil;
    if ([n userInfo]) {
        NSLog(@"MyDownloader returned an error");
    }
    else {
        data = [d receivedData];
        NSLog(@"MyDownloader returned the requested data");
    }
    [self.connections removeObject:d];
}

Solution

  • Baddidi gave the solution which is that I should have subclassed my class as an NSObject, not a NSURLConnection.